Refactor Support Kit tests

* Use CPPUNIT_TEST(_SUITE) macros and autoregistration.
* Remove unnecessary header files.
* Consolidate Archivable, Autolock, MemoryIO and MallocIO tests into
  one .cpp file.
* This structure makes it easier to add new tests - from adding .cpp
  and .h + updating Addon.cpp file (3 files), only one .cpp file is
  needed now.
* Convert string_utf8 test from standalone app to CppUnit test.

Change-Id: I18d90eb66b7cfc5576626b66ed85e47eb64547bf
Reviewed-on: https://review.haiku-os.org/c/haiku/+/10399
Reviewed-by: Kacper Kasper <[email protected]>
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Kacper Kasper
2026-03-04 17:58:38 +00:00
parent ff0cd4274c
commit bd6b50bed7
144 changed files with 6050 additions and 9221 deletions
+2
View File
@@ -1,6 +1,8 @@
#ifndef _beos_test_suite_addon_h_
#define _beos_test_suite_addon_h_
#include <cppunit/Portability.h>
class BTestSuite;
extern "C" CPPUNIT_API BTestSuite* getTestSuite();
@@ -4,6 +4,8 @@
//#include <memory>
#include <cppunit/TestCase.h>
#include <cppunit/TestResult.h>
#include <cppunit/Test.h>
#include <ThreadedTestCase.h>
#include <cppunit/TestCaller.h>
#include <TestShell.h>
#include <ThreadManager.h>
+669
View File
@@ -0,0 +1,669 @@
/*
* Copyright 2002-2026, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <Archivable.h>
#include <Debug.h>
#include <Entry.h>
#include <Message.h>
#include <Path.h>
#include <Roster.h>
#include <TestSuiteAddon.h>
#include <TestUtils.h>
#include <cppunit/Exception.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include "remoteobjectdef/RemoteTestObject.h"
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;
#ifndef TEST_R5
const char* gRemoteLib = "/lib/libsupporttest_RemoteTestObject.so";
#else
const char* gRemoteLib = "/lib/libsupporttest_RemoteTestObject_r5.so";
#endif
static void FormatAndThrow(int line, const char* file, const char* msg, int err)
{
std::string s("line: ");
char lineStr[32];
sprintf(lineStr, "%d", line);
s += lineStr;
s += " ";
s += file;
s += msg;
s += strerror(err);
s += "(";
sprintf(lineStr, "%d", err);
s += lineStr;
s += ")";
CppUnit::Exception re(s.c_str());
throw re;
}
#define FORMAT_AND_THROW(MSG, ERR) FormatAndThrow(__LINE__, __FILE__, MSG, ERR)
class TIOTest : public BArchivable {
public:
TIOTest(int32 i)
: fData(i)
{
}
TIOTest(BMessage* archive)
{
if (archive->FindInt32("TIOTest::data", &fData) != B_OK)
fData = 0;
}
int32 GetData() const { return fData; }
status_t Archive(BMessage* archive, bool deep = true) const
{
status_t err = archive->AddString("class", "TIOTest");
if (!err)
err = archive->AddInt32("TIOTest::data", fData);
return err;
}
static TIOTest* Instantiate(BMessage* archive)
{
if (validate_instantiation(archive, "TIOTest"))
return new TIOTest(archive);
return NULL;
}
private:
int32 fData;
};
class ArchivableTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(ArchivableTest);
//CPPUNIT_TEST(Perform_ZeroCodeNullArg_ReturnsError);
CPPUNIT_TEST(Archive_NullArchiveShallow_ReturnsBadValue);
CPPUNIT_TEST(Archive_ValidArchiveShallow_ReturnsOk);
CPPUNIT_TEST(Archive_NullArchiveDeep_ReturnsBadValue);
CPPUNIT_TEST(Archive_ValidArchiveDeep_ReturnsOk);
CPPUNIT_TEST_SUITE_END();
public:
void Perform_ZeroCodeNullArg_ReturnsError()
{
BArchivable archive;
CPPUNIT_ASSERT_EQUAL(B_ERROR, archive.Perform(0, NULL));
}
void Archive_NullArchiveShallow_ReturnsBadValue()
{
BArchivable archive;
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, archive.Archive(NULL, false));
}
void Archive_ValidArchiveShallow_ReturnsOk()
{
BMessage storage;
BArchivable archive;
CPPUNIT_ASSERT_EQUAL(B_OK, archive.Archive(&storage, false));
const char* name;
CPPUNIT_ASSERT_EQUAL(B_OK, storage.FindString("class", &name));
CPPUNIT_ASSERT_EQUAL(0, strcmp(name, "BArchivable"));
}
void Archive_NullArchiveDeep_ReturnsBadValue()
{
BArchivable archive;
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, archive.Archive(NULL, true));
}
void Archive_ValidArchiveDeep_ReturnsOk()
{
BMessage storage;
BArchivable archive;
CPPUNIT_ASSERT_EQUAL(B_OK, archive.Archive(&storage, true));
const char* name;
CPPUNIT_ASSERT_EQUAL(B_OK, storage.FindString("class", &name));
CPPUNIT_ASSERT_EQUAL(0, strcmp(name, "BArchivable"));
}
};
class FindInstantiationFuncTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(FindInstantiationFuncTest);
CPPUNIT_TEST(FindInstantiationFunc_NullArgs_ReturnsNull);
CPPUNIT_TEST(FindInstantiationFunc_InvalidClassNullSig_ReturnsNull);
CPPUNIT_TEST(FindInstantiationFunc_NullClassInvalidSig_ReturnsNull);
CPPUNIT_TEST(FindInstantiationFunc_InvalidClassAndSig_ReturnsNull);
//CPPUNIT_TEST(FindInstantiationFunc_LocalClassNullSig_ReturnsValidFunc);
//CPPUNIT_TEST(FindInstantiationFunc_RemoteClassNullSig_ReturnsNull);
CPPUNIT_TEST(FindInstantiationFunc_LocalClassInvalidSig_ReturnsNull);
CPPUNIT_TEST(FindInstantiationFunc_RemoteClassInvalidSig_ReturnsNull);
//CPPUNIT_TEST(FindInstantiationFunc_LocalClassValidSig_ReturnsNull);
CPPUNIT_TEST(FindInstantiationFunc_RemoteClassValidSig_ReturnsNull);
#ifndef TEST_R5
CPPUNIT_TEST(FindInstantiationFunc_Message_NullArchive_ReturnsNull);
#endif
CPPUNIT_TEST(FindInstantiationFunc_Message_InvalidClassNullSig_ReturnsNull);
CPPUNIT_TEST(FindInstantiationFunc_Message_NullClassInvalidSig_ReturnsNull);
CPPUNIT_TEST(FindInstantiationFunc_Message_InvalidClassAndSig_ReturnsNull);
//CPPUNIT_TEST(FindInstantiationFunc_Message_LocalClassNullSig_ReturnsValidFunc);
CPPUNIT_TEST(FindInstantiationFunc_Message_RemoteClassNullSig_ReturnsNull);
CPPUNIT_TEST(FindInstantiationFunc_Message_LocalClassInvalidSig_ReturnsNull);
CPPUNIT_TEST(FindInstantiationFunc_Message_RemoteClassInvalidSig_ReturnsNull);
//CPPUNIT_TEST(FindInstantiationFunc_Message_LocalClassValidSig_ReturnsNull);
CPPUNIT_TEST(FindInstantiationFunc_Message_RemoteClassValidSig_ReturnsNull);
CPPUNIT_TEST_SUITE_END();
public:
void FindInstantiationFunc_NullArgs_ReturnsNull()
{
instantiation_func f = find_instantiation_func(NULL, NULL);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_InvalidClassNullSig_ReturnsNull()
{
instantiation_func f = find_instantiation_func(gInvalidClassName, NULL);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_NullClassInvalidSig_ReturnsNull()
{
instantiation_func f = find_instantiation_func(NULL, gInvalidSig);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_InvalidClassAndSig_ReturnsNull()
{
instantiation_func f = find_instantiation_func(gInvalidClassName, gInvalidSig);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_LocalClassNullSig_ReturnsValidFunc()
{
instantiation_func f = find_instantiation_func(gLocalClassName, NULL);
CPPUNIT_ASSERT(f != NULL);
BMessage archive;
archive.AddString("class", gLocalClassName);
TIOTest* test = dynamic_cast<TIOTest*>(f(&archive));
CPPUNIT_ASSERT(test != NULL);
}
void FindInstantiationFunc_RemoteClassNullSig_ReturnsNull()
{
instantiation_func f = find_instantiation_func(gRemoteClassName, NULL);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_LocalClassInvalidSig_ReturnsNull()
{
instantiation_func f = find_instantiation_func(gLocalClassName, gInvalidSig);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_RemoteClassInvalidSig_ReturnsNull()
{
instantiation_func f = find_instantiation_func(gRemoteClassName, gInvalidSig);
CPPUNIT_ASSERT(f == NULL);
}
/**
* \note
* This test is not currently used; can't obtain the local
* signature without a BApplication object (gLocalSig is a
* placeholder).
*/
void FindInstantiationFunc_LocalClassValidSig_ReturnsNull()
{
instantiation_func f = find_instantiation_func(gLocalClassName, gLocalSig);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_RemoteClassValidSig_ReturnsNull()
{
instantiation_func f = find_instantiation_func(gRemoteClassName, gRemoteSig);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_Message_NullArchive_ReturnsNull()
{
instantiation_func f = find_instantiation_func((BMessage*)NULL);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_Message_InvalidClassNullSig_ReturnsNull()
{
BMessage archive;
archive.AddString("class", gInvalidClassName);
instantiation_func f = find_instantiation_func(&archive);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_Message_NullClassInvalidSig_ReturnsNull()
{
BMessage archive;
archive.AddString("add_on", gInvalidSig);
instantiation_func f = find_instantiation_func(&archive);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_Message_InvalidClassAndSig_ReturnsNull()
{
BMessage archive;
archive.AddString("class", gInvalidClassName);
archive.AddString("add_on", gInvalidSig);
instantiation_func f = find_instantiation_func(&archive);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_Message_LocalClassNullSig_ReturnsValidFunc()
{
BMessage archive;
archive.AddString("class", gLocalClassName);
instantiation_func f = find_instantiation_func(&archive);
CPPUNIT_ASSERT(f != NULL);
TIOTest* test = dynamic_cast<TIOTest*>(f(&archive));
CPPUNIT_ASSERT(test != NULL);
}
void FindInstantiationFunc_Message_RemoteClassNullSig_ReturnsNull()
{
BMessage archive;
archive.AddString("class", gRemoteClassName);
instantiation_func f = find_instantiation_func(&archive);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_Message_LocalClassInvalidSig_ReturnsNull()
{
BMessage archive;
archive.AddString("class", gLocalClassName);
archive.AddString("add_on", gInvalidSig);
instantiation_func f = find_instantiation_func(&archive);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_Message_RemoteClassInvalidSig_ReturnsNull()
{
BMessage archive;
archive.AddString("class", gRemoteClassName);
archive.AddString("add_on", gInvalidSig);
instantiation_func f = find_instantiation_func(&archive);
CPPUNIT_ASSERT(f == NULL);
}
/**
* \note
* This test is not currently used; can't obtain the local
* signature without a BApplication object (gLocalSig is a
* placeholder).
*/
void FindInstantiationFunc_Message_LocalClassValidSig_ReturnsNull()
{
BMessage archive;
archive.AddString("class", gLocalClassName);
archive.AddString("add_on", gLocalSig);
instantiation_func f = find_instantiation_func(&archive);
CPPUNIT_ASSERT(f == NULL);
}
void FindInstantiationFunc_Message_RemoteClassValidSig_ReturnsNull()
{
BMessage archive;
archive.AddString("class", gRemoteClassName);
archive.AddString("add_on", gRemoteSig);
instantiation_func f = find_instantiation_func(&archive);
CPPUNIT_ASSERT(f == NULL);
}
};
class InstantiateObjectTest : public CppUnit::TestFixture {
public:
InstantiateObjectTest() : fAddonId(B_ERROR) {}
CPPUNIT_TEST_SUITE(InstantiateObjectTest);
CPPUNIT_TEST(InstantiateObject_NullArchive_ReturnsNullAndBadValue);
CPPUNIT_TEST(InstantiateObject_NoClassName_ReturnsNull);
CPPUNIT_TEST(InstantiateObject_InvalidClassName_ReturnsNull);
CPPUNIT_TEST(InstantiateObject_InvalidClassAndSignature_ReturnsNull);
CPPUNIT_TEST(InstantiateObject_InvalidClassValidSignature_ReturnsNull);
CPPUNIT_TEST(InstantiateObject_LocalClass_ReturnsInstance);
CPPUNIT_TEST(InstantiateObject_LoadedRemoteClass_ReturnsInstance);
CPPUNIT_TEST(InstantiateObject_RemoteClassNoSignature_ReturnsNull);
CPPUNIT_TEST(InstantiateObject_LocalClassInvalidSignature_ReturnsNull);
CPPUNIT_TEST(InstantiateObject_LoadedRemoteClassInvalidSignature_ReturnsNull);
CPPUNIT_TEST(InstantiateObject_RemoteClassInvalidSignature_ReturnsNull);
CPPUNIT_TEST(InstantiateObject_LoadedRemoteClassValidSignature_ReturnsInstance);
CPPUNIT_TEST(InstantiateObject_RemoteClassValidSignature_ReturnsInstance);
CPPUNIT_TEST_SUITE_END();
void InstantiateObject_NullArchive_ReturnsNullAndBadValue()
{
errno = B_OK;
image_id id = B_OK;
TIOTest* test = (TIOTest*)instantiate_object(NULL, &id);
CPPUNIT_ASSERT(test == NULL);
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, id);
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, errno);
}
void InstantiateObject_NoClassName_ReturnsNull()
{
errno = B_OK;
BMessage archive;
image_id id = B_OK;
TIOTest* test = (TIOTest*)instantiate_object(&archive, &id);
CPPUNIT_ASSERT(test == NULL);
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, id);
CPPUNIT_ASSERT_EQUAL(B_OK, errno);
}
void InstantiateObject_InvalidClassName_ReturnsNull()
{
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_EQUAL(B_BAD_VALUE, id);
CPPUNIT_ASSERT_EQUAL(B_OK, errno);
}
void InstantiateObject_InvalidClassAndSignature_ReturnsNull()
{
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_EQUAL(B_BAD_VALUE, id);
CPPUNIT_ASSERT_EQUAL(B_LAUNCH_FAILED_APP_NOT_FOUND, errno);
}
void InstantiateObject_InvalidClassValidSignature_ReturnsNull()
{
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_EQUAL(B_BAD_VALUE, errno);
}
void InstantiateObject_LocalClass_ReturnsInstance()
{
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_EQUAL(B_BAD_VALUE, id);
CPPUNIT_ASSERT_EQUAL(B_OK, errno);
}
void InstantiateObject_LoadedRemoteClass_ReturnsInstance()
{
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_EQUAL(B_BAD_VALUE, id);
CPPUNIT_ASSERT_EQUAL(B_OK, errno);
UnloadAddon();
}
void InstantiateObject_RemoteClassNoSignature_ReturnsNull()
{
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_EQUAL(B_BAD_VALUE, id);
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, errno);
}
void InstantiateObject_LocalClassInvalidSignature_ReturnsNull()
{
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_EQUAL(B_BAD_VALUE, id);
CPPUNIT_ASSERT_EQUAL(B_LAUNCH_FAILED_APP_NOT_FOUND, errno);
}
void InstantiateObject_LoadedRemoteClassInvalidSignature_ReturnsNull()
{
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_EQUAL(B_BAD_VALUE, id);
CPPUNIT_ASSERT_EQUAL(B_LAUNCH_FAILED_APP_NOT_FOUND, errno);
UnloadAddon();
}
void InstantiateObject_RemoteClassInvalidSignature_ReturnsNull()
{
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_EQUAL(B_BAD_VALUE, id);
CPPUNIT_ASSERT_EQUAL(B_LAUNCH_FAILED_APP_NOT_FOUND, errno);
}
void InstantiateObject_LocalClassValidSignature_ReturnsInstance()
{
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_EQUAL(B_BAD_VALUE, id);
CPPUNIT_ASSERT_EQUAL(B_OK, errno);
}
void InstantiateObject_LoadedRemoteClassValidSignature_ReturnsInstance()
{
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_EQUAL(B_BAD_VALUE, id);
CPPUNIT_ASSERT_EQUAL(B_OK, errno);
UnloadAddon();
}
void InstantiateObject_RemoteClassValidSignature_ReturnsInstance()
{
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_EQUAL(B_OK, errno);
}
private:
void LoadAddon()
{
if (fAddonId > 0)
return;
std::string libPath("lib/");
libPath += gRemoteLib;
fAddonId = load_add_on(libPath.c_str());
if (fAddonId <= 0)
FORMAT_AND_THROW(" failed to load addon: ", fAddonId);
}
void 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 GetLocalSignature()
{
BRoster roster;
app_info ai;
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_info info;
err = get_team_info(ti.team, &info);
if (err)
FORMAT_AND_THROW(" failed to get team_info: ", err);
err = roster.GetRunningAppInfo(info.team, &ai);
if (err)
FORMAT_AND_THROW(" failed to get app_info: ", err);
return ai.signature;
}
private:
image_id fAddonId;
};
class ValidateInstantiationTest : public CppUnit::TestFixture {
public:
CPPUNIT_TEST_SUITE(ValidateInstantiationTest);
#ifndef TEST_R5
CPPUNIT_TEST(ValidateInstantiation_NullParams_ReturnsFalse);
CPPUNIT_TEST(ValidateInstantiation_NullArchive_ReturnsFalse);
#endif
CPPUNIT_TEST(ValidateInstantiation_NullClassName_ReturnsFalse);
CPPUNIT_TEST(ValidateInstantiation_NoClassField_ReturnsFalse);
CPPUNIT_TEST(ValidateInstantiation_MismatchedClassField_ReturnsFalse);
CPPUNIT_TEST(ValidateInstantiation_ValidParams_ReturnsTrue);
CPPUNIT_TEST_SUITE_END();
void ValidateInstantiation_NullParams_ReturnsFalse()
{
errno = B_OK;
CPPUNIT_ASSERT_EQUAL(false, validate_instantiation(NULL, NULL));
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, errno);
}
void ValidateInstantiation_NullClassName_ReturnsFalse()
{
errno = B_OK;
BMessage archive;
CPPUNIT_ASSERT_EQUAL(false, validate_instantiation(&archive, NULL));
CPPUNIT_ASSERT_EQUAL(B_MISMATCHED_VALUES, errno);
}
void ValidateInstantiation_NullArchive_ReturnsFalse()
{
errno = B_OK;
CPPUNIT_ASSERT_EQUAL(false, validate_instantiation(NULL, "FooBar"));
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, errno);
}
void ValidateInstantiation_NoClassField_ReturnsFalse()
{
errno = B_OK;
BMessage archive;
CPPUNIT_ASSERT_EQUAL(false, validate_instantiation(&archive, "FooBar"));
CPPUNIT_ASSERT_EQUAL(B_MISMATCHED_VALUES, errno);
}
void ValidateInstantiation_MismatchedClassField_ReturnsFalse()
{
errno = B_OK;
BMessage archive;
archive.AddString("class", "FooBar");
CPPUNIT_ASSERT_EQUAL(false, validate_instantiation(&archive, "BarFoo"));
CPPUNIT_ASSERT_EQUAL(B_MISMATCHED_VALUES, errno);
}
void ValidateInstantiation_ValidParams_ReturnsTrue()
{
errno = B_OK;
BMessage archive;
archive.AddString("class", "FooBar");
CPPUNIT_ASSERT_EQUAL(true, validate_instantiation(&archive, "FooBar"));
CPPUNIT_ASSERT_EQUAL(B_OK, errno);
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ArchivableTest, getTestSuiteName());
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(FindInstantiationFuncTest, getTestSuiteName());
// CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(InstantiateObjectTest, getTestSuiteName());
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ValidateInstantiationTest, getTestSuiteName());
+208
View File
@@ -0,0 +1,208 @@
/*
* Copyright 2002-2026, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* tylerdauwalder
*/
#include <Autolock.h>
#include <Looper.h>
#include <OS.h>
#include <TestSuiteAddon.h>
#include <ThreadedTestCase.h>
#include <ThreadedTestCaller.h>
#include <cppunit/TestSuite.h>
#include <cppunit/extensions/HelperMacros.h>
static const bigtime_t SNOOZE_TIME = 250000;
class AutolockLockerTest : public BThreadedTestCase {
public:
AutolockLockerTest(std::string name);
virtual ~AutolockLockerTest();
void Lock_Locker_MatchesThread();
void Construct_AutolockPtr_LocksLocker();
void Construct_AutolockRef_LocksLocker();
static CppUnit::Test* suite();
private:
BLocker* fLocker;
};
AutolockLockerTest::AutolockLockerTest(std::string name)
:
BThreadedTestCase(name),
fLocker(new BLocker)
{
}
AutolockLockerTest::~AutolockLockerTest()
{
delete fLocker;
}
/**
* This method performs the tests on the Autolock. It first acquires the
* lock and sleeps for a short time. It deletes the lock rather than Unlock()
* it in order to test the other two threads. Then, it constructs a new
* Locker and Autolock and checks that both the Autolock and the Locker are
* both locked. Then, the Autolock is released by deleting it. The Locker
* is checked to see that it is now released. This is then repeated for an Autolock
* constructed by passing a reference to the Locker.
*/
void
AutolockLockerTest::Lock_Locker_MatchesThread()
{
CPPUNIT_ASSERT(fLocker->Lock());
CPPUNIT_ASSERT(fLocker->LockingThread() == find_thread(NULL));
snooze(SNOOZE_TIME);
// Deleting the locker while others might be waiting is a destructive test
delete fLocker;
fLocker = new BLocker;
{
BAutolock autolock(fLocker);
CPPUNIT_ASSERT(fLocker->IsLocked());
CPPUNIT_ASSERT(fLocker->LockingThread() == find_thread(NULL));
CPPUNIT_ASSERT(autolock.IsLocked());
}
CPPUNIT_ASSERT(fLocker->LockingThread() != find_thread(NULL));
{
BAutolock autolock(*fLocker);
CPPUNIT_ASSERT(fLocker->IsLocked());
CPPUNIT_ASSERT(fLocker->LockingThread() == find_thread(NULL));
CPPUNIT_ASSERT(autolock.IsLocked());
}
CPPUNIT_ASSERT(fLocker->LockingThread() != find_thread(NULL));
}
/**
* This method performs the tests on the Autolock. It first sleeps for a short
* time and then tries to acquire the lock with an Autolock. It passes a pointer
* to the lock to the Autolock. It expects the acquisition to fail and IsLocked()
* is tested to be sure.
*/
void
AutolockLockerTest::Construct_AutolockPtr_LocksLocker()
{
snooze(SNOOZE_TIME / 10);
BAutolock autolock(fLocker);
CPPUNIT_ASSERT(!autolock.IsLocked());
}
/**
* This method performs the tests on the Autolock. It first sleeps for a short
* time and then tries to acquire the lock with an Autolock. It passes a reference
* to the lock to the Autolock. It expects the acquisition to fail and IsLocked()
* is tested to be sure.
*/
void
AutolockLockerTest::Construct_AutolockRef_LocksLocker()
{
snooze(SNOOZE_TIME / 10);
BAutolock autolock(*fLocker);
CPPUNIT_ASSERT(!autolock.IsLocked());
}
CppUnit::Test*
AutolockLockerTest::suite()
{
typedef BThreadedTestCaller<AutolockLockerTest> AutolockLockerTestCaller;
AutolockLockerTest* theTest = new AutolockLockerTest("");
AutolockLockerTestCaller* threadedTest
= new AutolockLockerTestCaller("BAutolock::Locker Test", theTest);
threadedTest->addThread("A", &AutolockLockerTest::Lock_Locker_MatchesThread);
threadedTest->addThread("B", &AutolockLockerTest::Construct_AutolockPtr_LocksLocker);
threadedTest->addThread("C", &AutolockLockerTest::Construct_AutolockRef_LocksLocker);
return threadedTest;
}
class AutolockLooperTest : public BThreadedTestCase {
public:
AutolockLooperTest(std::string name);
virtual ~AutolockLooperTest();
void Construct_AutolockPtr_LocksLooper();
static CppUnit::Test* suite();
private:
BLooper* fLooper;
};
AutolockLooperTest::AutolockLooperTest(std::string name)
:
BThreadedTestCase(name),
fLooper(new BLooper)
{
fLooper->Run();
}
AutolockLooperTest::~AutolockLooperTest()
{
if (fLooper != NULL) {
fLooper->Lock();
fLooper->Quit();
}
}
/**
* This method performs the tests on the Autolock. It constructs a new
* Autolock and checks that both the Autolock and the Looper are
* both locked. Then, the Autolock is released by deleting it. The Looper
* is checked to see that it is now released.
*/
void
AutolockLooperTest::Construct_AutolockPtr_LocksLooper()
{
BAutolock* autolock = new BAutolock(fLooper);
CPPUNIT_ASSERT(fLooper->IsLocked());
CPPUNIT_ASSERT(fLooper->LockingThread() == find_thread(NULL));
CPPUNIT_ASSERT(autolock->IsLocked());
delete autolock;
CPPUNIT_ASSERT(fLooper->LockingThread() != find_thread(NULL));
}
CppUnit::Test*
AutolockLooperTest::suite()
{
typedef BThreadedTestCaller<AutolockLooperTest> AutolockLooperTestCaller;
AutolockLooperTest* theTest = new AutolockLooperTest("");
AutolockLooperTestCaller* threadedTest
= new AutolockLooperTestCaller("BAutolock::Looper Test", theTest);
threadedTest->addThread("A", &AutolockLooperTest::Construct_AutolockPtr_LocksLooper);
return threadedTest;
}
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(AutolockLockerTest, getTestSuiteName());
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(AutolockLooperTest, getTestSuiteName());
@@ -1,17 +1,49 @@
/*
This file tests BBlockCache from multiple threads to ensure there are
no concurrency problems.
*/
* Copyright 2003-2026, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "BlockCacheConcurrencyTest.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <BlockCache.h>
#include <List.h>
#include "ThreadedTestCaller.h"
#include <TestSuiteAddon.h>
#include <ThreadedTestCaller.h>
#include <ThreadedTestCase.h>
#include <cppunit/TestFixture.h>
#include <cppunit/TestSuite.h>
#include <cppunit/extensions/HelperMacros.h>
class BlockCacheConcurrencyTest : public BThreadedTestCase {
private:
BBlockCache *theObjCache;
BBlockCache *theMallocCache;
int numBlocksInCache;
size_t sizeOfBlocksInCache;
size_t sizeOfNonCacheBlocks;
void *GetBlock(BBlockCache *theCache, size_t blockSize,
thread_id theThread, BList *cacheList, BList *nonCacheList);
void SaveBlock(BBlockCache *theCache, void *, size_t blockSize,
thread_id theThread, BList *cacheList, BList *nonCacheList);
void FreeBlock(void *, size_t blockSize, bool isMallocTest,
thread_id theThread, BList *cacheList,
BList *nonCacheList);
void TestBlockCache(BBlockCache *theCache, bool isMallocTest);
public:
static CppUnit::Test *suite(void);
void TestThreadObj(void);
void TestThreadMalloc(void);
virtual void setUp(void);
virtual void tearDown(void);
BlockCacheConcurrencyTest(std::string);
virtual ~BlockCacheConcurrencyTest();
};
/*
@@ -49,10 +81,8 @@ BlockCacheConcurrencyTest::~BlockCacheConcurrencyTest()
void
BlockCacheConcurrencyTest::setUp()
{
theObjCache = new BBlockCache(numBlocksInCache, sizeOfBlocksInCache,
B_OBJECT_CACHE);
theMallocCache = new BBlockCache(numBlocksInCache, sizeOfBlocksInCache,
B_MALLOC_CACHE);
theObjCache = new BBlockCache(numBlocksInCache, sizeOfBlocksInCache, B_OBJECT_CACHE);
theMallocCache = new BBlockCache(numBlocksInCache, sizeOfBlocksInCache, B_MALLOC_CACHE);
}
@@ -73,27 +103,26 @@ BlockCacheConcurrencyTest::tearDown()
* Descr: This method returns a pointer from the BBlockCache, checking
* the value before passing it to the caller.
*/
void *
BlockCacheConcurrencyTest::GetBlock(BBlockCache *theCache, size_t blockSize,
thread_id theThread, BList *cacheList, BList *nonCacheList)
void*
BlockCacheConcurrencyTest::GetBlock(BBlockCache* theCache, size_t blockSize, thread_id theThread,
BList* cacheList, BList* nonCacheList)
{
void *thePtr = theCache->Get(blockSize);
void* thePtr = theCache->Get(blockSize);
// The new block should not already be used by this thread.
CPPUNIT_ASSERT(!cacheList->HasItem(thePtr));
CPPUNIT_ASSERT(!nonCacheList->HasItem(thePtr));
// Add the block to the list of blocks used by this thread.
if (blockSize == sizeOfBlocksInCache) {
if (blockSize == sizeOfBlocksInCache)
CPPUNIT_ASSERT(cacheList->AddItem(thePtr));
} else {
else
CPPUNIT_ASSERT(nonCacheList->AddItem(thePtr));
}
// Store the thread id at the start of the block for future
// reference.
*((thread_id *)thePtr) = theThread;
return(thePtr);
*((thread_id*)thePtr) = theThread;
return thePtr;
}
@@ -103,15 +132,14 @@ BlockCacheConcurrencyTest::GetBlock(BBlockCache *theCache, size_t blockSize,
* and checks the sanity of the lists.
*/
void
BlockCacheConcurrencyTest::SaveBlock(BBlockCache *theCache, void *thePtr,
size_t blockSize, thread_id theThread, BList *cacheList,
BList *nonCacheList)
BlockCacheConcurrencyTest::SaveBlock(BBlockCache* theCache, void* thePtr, size_t blockSize,
thread_id theThread, BList* cacheList, BList* nonCacheList)
{
// The block being returned to the cache should still have
// the thread id of this thread in it, or some other thread has
// perhaps manipulated this block which would indicate a
// concurrency problem.
CPPUNIT_ASSERT(*((thread_id *)thePtr) == theThread);
CPPUNIT_ASSERT(*((thread_id*)thePtr) == theThread);
// Remove the item from the appropriate list and confirm it isn't
// on the other list for some reason.
@@ -132,15 +160,14 @@ BlockCacheConcurrencyTest::SaveBlock(BBlockCache *theCache, void *thePtr,
* checking the sanity of the lists as it does the operation.
*/
void
BlockCacheConcurrencyTest::FreeBlock(void *thePtr, size_t blockSize,
bool isMallocTest, thread_id theThread, BList *cacheList,
BList *nonCacheList)
BlockCacheConcurrencyTest::FreeBlock(void* thePtr, size_t blockSize, bool isMallocTest,
thread_id theThread, BList* cacheList, BList* nonCacheList)
{
// The block being returned to the cache should still have
// the thread id of this thread in it, or some other thread has
// perhaps manipulated this block which would indicate a
// concurrency problem.
CPPUNIT_ASSERT(*((thread_id *)thePtr) == theThread);
CPPUNIT_ASSERT(*((thread_id*)thePtr) == theThread);
// Remove the item from the appropriate list and confirm it isn't
// on the other list for some reason.
@@ -151,11 +178,10 @@ BlockCacheConcurrencyTest::FreeBlock(void *thePtr, size_t blockSize,
CPPUNIT_ASSERT(!cacheList->HasItem(thePtr));
CPPUNIT_ASSERT(nonCacheList->RemoveItem(thePtr));
}
if (isMallocTest) {
if (isMallocTest)
free(thePtr);
} else {
else
delete[] (uint8*)thePtr;
}
}
@@ -174,8 +200,7 @@ BlockCacheConcurrencyTest::FreeBlock(void *thePtr, size_t blockSize,
* freed to avoid a memory leak.
*/
void
BlockCacheConcurrencyTest::TestBlockCache(BBlockCache *theCache,
bool isMallocTest)
BlockCacheConcurrencyTest::TestBlockCache(BBlockCache* theCache, bool isMallocTest)
{
BList cacheList;
BList nonCacheList;
@@ -191,8 +216,8 @@ BlockCacheConcurrencyTest::TestBlockCache(BBlockCache *theCache,
GetBlock(theCache, sizeOfNonCacheBlocks, theThread, &cacheList, &nonCacheList);
GetBlock(theCache, sizeOfNonCacheBlocks, theThread, &cacheList, &nonCacheList);
SaveBlock(theCache, cacheList.ItemAt(cacheList.CountItems() / 2),
sizeOfBlocksInCache, theThread, &cacheList, &nonCacheList);
SaveBlock(theCache, cacheList.ItemAt(cacheList.CountItems() / 2), sizeOfBlocksInCache,
theThread, &cacheList, &nonCacheList);
SaveBlock(theCache, nonCacheList.ItemAt(nonCacheList.CountItems() / 2),
sizeOfNonCacheBlocks, theThread, &cacheList, &nonCacheList);
@@ -201,31 +226,31 @@ BlockCacheConcurrencyTest::TestBlockCache(BBlockCache *theCache,
GetBlock(theCache, sizeOfNonCacheBlocks, theThread, &cacheList, &nonCacheList);
GetBlock(theCache, sizeOfNonCacheBlocks, theThread, &cacheList, &nonCacheList);
FreeBlock(cacheList.ItemAt(cacheList.CountItems() / 2),
sizeOfBlocksInCache, isMallocTest, theThread, &cacheList, &nonCacheList);
FreeBlock(nonCacheList.ItemAt(nonCacheList.CountItems() / 2),
sizeOfNonCacheBlocks, isMallocTest, theThread, &cacheList, &nonCacheList);
FreeBlock(cacheList.ItemAt(cacheList.CountItems() / 2), sizeOfBlocksInCache,
isMallocTest, theThread, &cacheList, &nonCacheList);
FreeBlock(nonCacheList.ItemAt(nonCacheList.CountItems() / 2), sizeOfNonCacheBlocks,
isMallocTest, theThread, &cacheList, &nonCacheList);
}
bool performFree = false;
// Free or save (every other block) for all "cache sized" blocks.
while (!cacheList.IsEmpty()) {
if (performFree) {
FreeBlock(cacheList.LastItem(), sizeOfBlocksInCache, isMallocTest, theThread, &cacheList,
&nonCacheList);
FreeBlock(cacheList.LastItem(), sizeOfBlocksInCache, isMallocTest, theThread,
&cacheList, &nonCacheList);
} else {
SaveBlock(theCache, cacheList.LastItem(), sizeOfBlocksInCache, theThread, &cacheList,
&nonCacheList);
SaveBlock(theCache, cacheList.LastItem(), sizeOfBlocksInCache, theThread,
&cacheList, &nonCacheList);
}
performFree = !performFree;
}
// Free or save (every other block) for all "non-cache sized" blocks.
while (!nonCacheList.IsEmpty()) {
if (performFree) {
FreeBlock(nonCacheList.LastItem(), sizeOfNonCacheBlocks, isMallocTest, theThread, &cacheList,
&nonCacheList);
FreeBlock(nonCacheList.LastItem(), sizeOfNonCacheBlocks, isMallocTest, theThread,
&cacheList, &nonCacheList);
} else {
SaveBlock(theCache, nonCacheList.LastItem(), sizeOfNonCacheBlocks, theThread, &cacheList,
&nonCacheList);
SaveBlock(theCache, nonCacheList.LastItem(), sizeOfNonCacheBlocks, theThread,
&cacheList, &nonCacheList);
}
performFree = !performFree;
}
@@ -263,18 +288,22 @@ BlockCacheConcurrencyTest::TestThreadObj()
* the "BlockCacheConcurrencyTest" test. The test caller
* is created as a ThreadedTestCaller with six independent threads.
*/
CppUnit::Test *BlockCacheConcurrencyTest::suite()
CppUnit::Test*
BlockCacheConcurrencyTest::suite()
{
typedef BThreadedTestCaller <BlockCacheConcurrencyTest >
BlockCacheConcurrencyTestCaller;
typedef BThreadedTestCaller<BlockCacheConcurrencyTest> BlockCacheConcurrencyTestCaller;
BlockCacheConcurrencyTest *theTest = new BlockCacheConcurrencyTest("");
BlockCacheConcurrencyTestCaller *threadedTest = new BlockCacheConcurrencyTestCaller("BBlockCache::Concurrency Test", theTest);
BlockCacheConcurrencyTest* theTest = new BlockCacheConcurrencyTest("");
BlockCacheConcurrencyTestCaller* threadedTest
= new BlockCacheConcurrencyTestCaller("BBlockCache::Concurrency Test", theTest);
threadedTest->addThread("A", &BlockCacheConcurrencyTest::TestThreadObj);
threadedTest->addThread("B", &BlockCacheConcurrencyTest::TestThreadObj);
threadedTest->addThread("C", &BlockCacheConcurrencyTest::TestThreadObj);
threadedTest->addThread("D", &BlockCacheConcurrencyTest::TestThreadMalloc);
threadedTest->addThread("E", &BlockCacheConcurrencyTest::TestThreadMalloc);
threadedTest->addThread("F", &BlockCacheConcurrencyTest::TestThreadMalloc);
return(threadedTest);
return threadedTest;
}
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BlockCacheConcurrencyTest, getTestSuiteName());
@@ -1,15 +1,46 @@
/*
This file tests basic functionality of BBlockCache.
*/
* Copyright 2003-2026, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "BlockCacheExerciseTest.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <BlockCache.h>
#include <List.h>
#include "cppunit/TestCaller.h"
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/TestSuite.h>
#include <cppunit/extensions/HelperMacros.h>
class BlockCacheExerciseTest : public CppUnit::TestCase {
private:
BBlockCache* theCache;
int numBlocksInCache;
size_t sizeOfBlocksInCache;
size_t sizeOfNonCacheBlocks;
bool isMallocTest;
BList freeList;
BList usedList;
BList nonCacheList;
void BuildLists(void);
void* GetBlock(size_t blockSize);
void SaveBlock(void*, size_t blockSize);
void FreeBlock(void*, size_t blockSize);
void TestBlockCache(void);
public:
static CppUnit::Test* suite(void);
BlockCacheExerciseTest(std::string = "");
virtual ~BlockCacheExerciseTest();
virtual void PerformTest(void);
};
/*
@@ -56,49 +87,46 @@ BlockCacheExerciseTest::~BlockCacheExerciseTest()
* A, B, C, D
* If five blocks are gotten from the cache, the caller will get
* A, B, C, D, E
* However, E wasn't initially part of the cache. It was allocated
* dynamically to satisfy the caller's request because the cache
* was empty. Now, if they are returned in the order E, D, C, B, A
* the cache will have the following blocks available in it:
* B, C, D, E
* When A is returned, the cache will find there is no more room
* for more free blocks and it will be freed. This is the
* behaviour which is confirmed initially.
* However, E wasn't initially part of the cache. It was
* allocated dynamically to satisfy the caller's request because
* the cache was empty. Now, if they are returned in the order
* E, D, C, B, A the cache will have the following blocks
* available in it: B, C, D, E When A is returned, the cache will
* find there is no more room for more free blocks and it will be
* freed. This is the behaviour which is confirmed initially.
*
* 2. After this is done, the cache is just "exercised". The following
* is done "numBlocksInCache" times:
* 2. After this is done, the cache is just "exercised". The
* following is done "numBlocksInCache" times:
* - 4 "cache sized" blocks are gotten from the cache
* - 4 "non-cache sized" blocks are gotten from the cache
* - 1 "cache sized" block is returned back to the cache
* - 1 "non-cache sized" block is returned back to the cache
* - 1 "cache sized" block is freed and not returned to the cache
* - 1 "cache sized" block is freed and not returned to the
* cache
* - 1 "non-cache sized" block is freed and not returned to the
* cache (but even if given to the BBlockCache, it would just
* be freed anyhow)
* What this means is that everytime through the loop, 2 "cache sized"
* and 2 "non-cache sized" blocks are kept in memory. At the end,
* 2 * numBlocksInCache items of size "cache size" and "non cache size"
* will exist.
* What this means is that everytime through the loop, 2 "cache
* sized" and 2 "non-cache sized" blocks are kept in memory. At
* the end, 2 * numBlocksInCache items of size "cache size" and
* "non cache size" will exist.
*
* Then, numBlocksInCache / 4 items are returned to the cache and
* numBlocksInCache / 4 are freed. This ensures at the end of the
* test that there are some available blocks in the cache.
* Then, numBlocksInCache / 4 items are returned to the cache
* and numBlocksInCache / 4 are freed. This ensures at the end
* of the test that there are some available blocks in the cache.
*
* The sum total of these actions test the BBlockCache.
*/
void
BlockCacheExerciseTest::TestBlockCache(void)
{
// First get all items from the cache plus ten more
for (int i = 0; i < numBlocksInCache + 10; i++) {
for (int i = 0; i < numBlocksInCache + 10; i++)
GetBlock(sizeOfBlocksInCache);
}
// Put them all back in reverse order to confirm 1 from above
while (!usedList.IsEmpty()) {
while (!usedList.IsEmpty())
SaveBlock(usedList.LastItem(), sizeOfBlocksInCache);
}
// Get a bunch of blocks and send some back to the cache
// to confirm 2 from above.
@@ -110,10 +138,8 @@ BlockCacheExerciseTest::TestBlockCache(void)
// We send one back from the middle of the lists so
// the most recent block is not the one returned.
SaveBlock(usedList.ItemAt(usedList.CountItems() / 2),
sizeOfBlocksInCache);
SaveBlock(nonCacheList.ItemAt(nonCacheList.CountItems() / 2),
sizeOfNonCacheBlocks);
SaveBlock(usedList.ItemAt(usedList.CountItems() / 2), sizeOfBlocksInCache);
SaveBlock(nonCacheList.ItemAt(nonCacheList.CountItems() / 2), sizeOfNonCacheBlocks);
GetBlock(sizeOfBlocksInCache);
GetBlock(sizeOfBlocksInCache);
@@ -122,10 +148,8 @@ BlockCacheExerciseTest::TestBlockCache(void)
// We free one from the middle of the lists so the
// most recent block is not the one freed.
FreeBlock(usedList.ItemAt(usedList.CountItems() / 2),
sizeOfBlocksInCache);
FreeBlock(nonCacheList.ItemAt(nonCacheList.CountItems() / 2),
sizeOfNonCacheBlocks);
FreeBlock(usedList.ItemAt(usedList.CountItems() / 2), sizeOfBlocksInCache);
FreeBlock(nonCacheList.ItemAt(nonCacheList.CountItems() / 2), sizeOfNonCacheBlocks);
}
// Now, send some blocks back to the cache and free some blocks
@@ -133,16 +157,12 @@ BlockCacheExerciseTest::TestBlockCache(void)
for (int i = 0; i < numBlocksInCache / 4; i++) {
// Return the blocks which are 2/3s of the way through the
// lists.
SaveBlock(usedList.ItemAt(usedList.CountItems() * 2 / 3),
sizeOfBlocksInCache);
SaveBlock(nonCacheList.ItemAt(nonCacheList.CountItems() * 2 / 3),
sizeOfNonCacheBlocks);
SaveBlock(usedList.ItemAt(usedList.CountItems() * 2 / 3), sizeOfBlocksInCache);
SaveBlock(nonCacheList.ItemAt(nonCacheList.CountItems() * 2 / 3), sizeOfNonCacheBlocks);
// Free the blocks which are 1/3 of the way through the lists.
FreeBlock(usedList.ItemAt(usedList.CountItems() / 3),
sizeOfBlocksInCache);
FreeBlock(nonCacheList.ItemAt(nonCacheList.CountItems() / 3),
sizeOfNonCacheBlocks);
FreeBlock(usedList.ItemAt(usedList.CountItems() / 3), sizeOfBlocksInCache);
FreeBlock(nonCacheList.ItemAt(nonCacheList.CountItems() / 3), sizeOfNonCacheBlocks);
}
}
@@ -163,12 +183,10 @@ BlockCacheExerciseTest::BuildLists()
usedList.MakeEmpty();
nonCacheList.MakeEmpty();
for(int i = 0; i < numBlocksInCache; i++) {
for (int i = 0; i < numBlocksInCache; i++)
freeList.AddItem(theCache->Get(sizeOfBlocksInCache));
}
for(int i = 0; i < numBlocksInCache; i++) {
for (int i = 0; i < numBlocksInCache; i++)
theCache->Save(freeList.ItemAt(i), sizeOfBlocksInCache);
}
}
@@ -177,10 +195,10 @@ BlockCacheExerciseTest::BuildLists()
* Descr: This method returns a pointer from the BBlockCache, checking
* the value before passing it to the caller.
*/
void *
void*
BlockCacheExerciseTest::GetBlock(size_t blockSize)
{
void *thePtr = theCache->Get(blockSize);
void* thePtr = theCache->Get(blockSize);
// This new pointer should not be one which we already
// have from the BBlockCache which we haven't given back
@@ -192,9 +210,8 @@ BlockCacheExerciseTest::GetBlock(size_t blockSize)
// If this block was one which could have come from the
// cache and there are free items on the cache, it
// should be one of those free blocks.
if (freeList.CountItems() > 0) {
if (freeList.CountItems() > 0)
CPPUNIT_ASSERT(freeList.RemoveItem(thePtr));
}
CPPUNIT_ASSERT(usedList.AddItem(thePtr));
} else {
// A "non-cache sized" block should never come from the
@@ -202,7 +219,7 @@ BlockCacheExerciseTest::GetBlock(size_t blockSize)
CPPUNIT_ASSERT(!freeList.HasItem(thePtr));
CPPUNIT_ASSERT(nonCacheList.AddItem(thePtr));
}
return(thePtr);
return thePtr;
}
@@ -212,7 +229,7 @@ BlockCacheExerciseTest::GetBlock(size_t blockSize)
* and checks the sanity of the lists.
*/
void
BlockCacheExerciseTest::SaveBlock(void *thePtr, size_t blockSize)
BlockCacheExerciseTest::SaveBlock(void* thePtr, size_t blockSize)
{
// The memory block being returned to the cache should
// not already be free.
@@ -223,9 +240,8 @@ BlockCacheExerciseTest::SaveBlock(void *thePtr, size_t blockSize)
// is returned to the cache, it will be put on the
// free list. Therefore we will also track it as
// a free block on the cache.
if (freeList.CountItems() < numBlocksInCache) {
if (freeList.CountItems() < numBlocksInCache)
CPPUNIT_ASSERT(freeList.AddItem(thePtr));
}
// This block should not be on the non-cache list but it
// should be on the used list.
@@ -247,7 +263,7 @@ BlockCacheExerciseTest::SaveBlock(void *thePtr, size_t blockSize)
* checking the sanity of the lists as it does the operation.
*/
void
BlockCacheExerciseTest::FreeBlock(void *thePtr, size_t blockSize)
BlockCacheExerciseTest::FreeBlock(void* thePtr, size_t blockSize)
{
// The block being freed should not already have been
// returned to the cache.
@@ -264,11 +280,10 @@ BlockCacheExerciseTest::FreeBlock(void *thePtr, size_t blockSize)
CPPUNIT_ASSERT(!usedList.HasItem(thePtr));
CPPUNIT_ASSERT(nonCacheList.RemoveItem(thePtr));
}
if (isMallocTest) {
if (isMallocTest)
free(thePtr);
} else {
else
delete[] (uint8*)thePtr;
}
}
@@ -306,12 +321,10 @@ BlockCacheExerciseTest::PerformTest(void)
TestBlockCache();
delete theCache;
// Clean up remaining memory.
while (!usedList.IsEmpty()) {
while (!usedList.IsEmpty())
FreeBlock(usedList.LastItem(), sizeOfBlocksInCache);
}
while (!nonCacheList.IsEmpty()) {
while (!nonCacheList.IsEmpty())
FreeBlock(nonCacheList.LastItem(), sizeOfNonCacheBlocks);
}
isMallocTest = true;
theCache = new BBlockCache(numBlocksInCache, sizeOfBlocksInCache, B_MALLOC_CACHE);
@@ -323,14 +336,12 @@ BlockCacheExerciseTest::PerformTest(void)
TestBlockCache();
delete theCache;
// Clean up remaining memory.
while (!usedList.IsEmpty()) {
while (!usedList.IsEmpty())
FreeBlock(usedList.LastItem(), sizeOfBlocksInCache);
}
while (!nonCacheList.IsEmpty()) {
while (!nonCacheList.IsEmpty())
FreeBlock(nonCacheList.LastItem(), sizeOfNonCacheBlocks);
}
}
}
}
@@ -339,13 +350,14 @@ BlockCacheExerciseTest::PerformTest(void)
* Descr: This static member function returns a test caller for performing
* the "BlockCacheExerciseTest" test.
*/
CppUnit::Test *BlockCacheExerciseTest::suite()
CppUnit::Test*
BlockCacheExerciseTest::suite()
{
typedef CppUnit::TestCaller<BlockCacheExerciseTest>
BlockCacheExerciseTestCaller;
typedef CppUnit::TestCaller<BlockCacheExerciseTest> BlockCacheExerciseTestCaller;
return(new BlockCacheExerciseTestCaller("BBlockCache::Exercise Test", &BlockCacheExerciseTest::PerformTest));
return new BlockCacheExerciseTestCaller("BBlockCache::Exercise Test",
&BlockCacheExerciseTest::PerformTest);
}
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BlockCacheExerciseTest, getTestSuiteName());
+85 -66
View File
@@ -9,20 +9,19 @@
#include <ByteOrder.h>
#include <TestCase.h>
#include <TestSuiteAddon.h>
#include <TestUtils.h>
#include <cppunit/TestFixture.h>
#include <cppunit/TestSuite.h>
#include <cppunit/extensions/HelperMacros.h>
using CppUnit::TestFixture;
// ToDo: swap_int16() and friends don't really belong here as they are in
// libroot.so
// The tests might be messed up because of that, and don't test the real
// thing, as long as they don't run on Haiku itself.
// ToDo: swap_int16() and friends don't really belong here as they are in libroot.so
// The tests might be messed up because of that, and don't test the real thing, as
// long as they don't run on Haiku itself.
class ByteOrderTest : public TestFixture {
class ByteOrderTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(ByteOrderTest);
CPPUNIT_TEST(Swap16_InputZero_RemainsZero);
@@ -52,77 +51,91 @@ class ByteOrderTest : public TestFixture {
CPPUNIT_TEST(IsTypeSwapped);
CPPUNIT_TEST_SUITE_END();
public:
void Swap16_InputZero_RemainsZero() {
void Swap16_InputZero_RemainsZero()
{
uint16 input = 0;
CHK(input == __swap_int16(input));
CPPUNIT_ASSERT_EQUAL(input, __swap_int16(input));
}
void Swap16_InputAscending_SwapsBytes() {
void Swap16_InputAscending_SwapsBytes()
{
int16 input = 0x1234;
uint16 expected = 0x3412;
CHK(expected == __swap_int16(input));
CPPUNIT_ASSERT_EQUAL(expected, __swap_int16(input));
}
void Swap16_InputNegative_SwapsBytes() {
void Swap16_InputNegative_SwapsBytes()
{
int16 input = 0xfedc;
uint16 expected = 0xdcfe;
CHK(expected == __swap_int16(input));
CPPUNIT_ASSERT_EQUAL(expected, __swap_int16(input));
}
void Swap16_InputMixed_SwapsBytes() {
void Swap16_InputMixed_SwapsBytes()
{
uint16 input = 0xfefd;
uint16 expected = 0xfdfe;
CHK(expected == __swap_int16(input));
CPPUNIT_ASSERT_EQUAL(expected, __swap_int16(input));
}
void Swap32_InputZero_RemainsZero() {
void Swap32_InputZero_RemainsZero()
{
uint32 input = 0;
CHK(input == __swap_int32(input));
CPPUNIT_ASSERT_EQUAL(input, __swap_int32(input));
}
void Swap32_InputAscending_SwapsBytes() {
void Swap32_InputAscending_SwapsBytes()
{
int32 input = 0x12345678;
uint32 expected = 0x78563412;
CHK(expected == __swap_int32(input));
CPPUNIT_ASSERT_EQUAL(expected, __swap_int32(input));
}
void Swap32_InputNegative_SwapsBytes() {
void Swap32_InputNegative_SwapsBytes()
{
int32 input = 0xfedcba98;
uint32 expected = 0x98badcfe;
CHK(expected == __swap_int32(input));
CPPUNIT_ASSERT_EQUAL(expected, __swap_int32(input));
}
void Swap32_InputMixed_SwapsBytes() {
void Swap32_InputMixed_SwapsBytes()
{
uint32 input = 0xfefdfcfb;
uint32 expected = 0xfbfcfdfe;
CHK(expected == __swap_int32(input));
CPPUNIT_ASSERT_EQUAL(expected, __swap_int32(input));
}
void Swap64_InputZero_RemainsZero() {
void Swap64_InputZero_RemainsZero()
{
uint64 input = 0;
CHK(input == __swap_int64(input));
CPPUNIT_ASSERT_EQUAL(input, __swap_int64(input));
}
void Swap64_InputAscending_SwapsBytes() {
void Swap64_InputAscending_SwapsBytes()
{
int64 input = 0x1234567890000000LL;
uint64 expected = 0x0000009078563412LL;
CHK(expected == __swap_int64(input));
CPPUNIT_ASSERT_EQUAL(expected, __swap_int64(input));
}
void Swap64_InputNegative_SwapsBytes() {
void Swap64_InputNegative_SwapsBytes()
{
int64 input = 0xfedcba9876543210LL;
uint64 expected = 0x1032547698badcfeLL;
CHK(expected == __swap_int64(input));
CPPUNIT_ASSERT_EQUAL(expected, __swap_int64(input));
}
void Swap64_InputMixed_SwapsBytes() {
void Swap64_InputMixed_SwapsBytes()
{
uint64 input = 0xfefdLL;
uint64 expected = 0xfdfe000000000000LL;
CHK(expected == __swap_int64(input));
CPPUNIT_ASSERT_EQUAL(expected, __swap_int64(input));
}
void SwapFloat_Roundtrip_ReturnsInput() {
void SwapFloat_Roundtrip_ReturnsInput()
{
const float kNumber = 1.125;
const float kNaN = NAN;
const float kInfinity = HUGE_VALF;
@@ -133,12 +146,13 @@ public:
memcpy(&dataNaN, &roundtrip, sizeof(float));
memcpy(&expectedNaN, &kNaN, sizeof(float));
CHK(kNumber == __swap_float(__swap_float(kNumber)));
CHK(expectedNaN == dataNaN); // NaN == NaN as floats returns false
CHK(kInfinity == __swap_float(__swap_float(kInfinity)));
CPPUNIT_ASSERT_EQUAL(kNumber, __swap_float(__swap_float(kNumber)));
CPPUNIT_ASSERT_EQUAL(expectedNaN, dataNaN); // NaN == NaN as floats returns false
CPPUNIT_ASSERT_EQUAL(kInfinity, __swap_float(__swap_float(kInfinity)));
}
void SwapDouble_Roundtrip_ReturnsInput() {
void SwapDouble_Roundtrip_ReturnsInput()
{
const double kNumber = 1.125;
const double kNaN = NAN;
const double kInfinity = HUGE_VAL;
@@ -149,63 +163,68 @@ public:
memcpy(&dataNaN, &roundtrip, sizeof(double));
memcpy(&expectedNaN, &kNaN, sizeof(double));
CHK(kNumber == __swap_double(__swap_double(kNumber)));
CHK(expectedNaN == dataNaN); // NaN == NaN as floats returns false
CHK(kInfinity == __swap_double(__swap_double(kInfinity)));
CPPUNIT_ASSERT_EQUAL(kNumber, __swap_double(__swap_double(kNumber)));
CPPUNIT_ASSERT_EQUAL(expectedNaN, dataNaN); // NaN == NaN as floats returns false
CPPUNIT_ASSERT_EQUAL(kInfinity, __swap_double(__swap_double(kInfinity)));
}
void SwapData_StringType_ReturnsBadValue() {
void SwapData_StringType_ReturnsBadValue()
{
char str[4];
CHK(swap_data(B_STRING_TYPE, str, 4, B_SWAP_ALWAYS) == B_BAD_VALUE);
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, swap_data(B_STRING_TYPE, str, 4, B_SWAP_ALWAYS));
}
void SwapData_Int32TypeInputWithZeroLength_ReturnsOK() {
void SwapData_Int32TypeInputWithZeroLength_ReturnsOK()
{
int32 num32 = 0;
CHK(swap_data(B_INT32_TYPE, &num32, 0, B_SWAP_ALWAYS) == B_OK);
CPPUNIT_ASSERT_EQUAL(B_OK, swap_data(B_INT32_TYPE, &num32, 0, B_SWAP_ALWAYS));
}
void SwapData_Int32TypeWithNullInputSwapAlways_ReturnsBadValue() {
CHK(swap_data(B_INT32_TYPE, NULL, 4, B_SWAP_ALWAYS) == B_BAD_VALUE);
void SwapData_Int32TypeWithNullInputSwapAlways_ReturnsBadValue()
{
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, swap_data(B_INT32_TYPE, NULL, 4, B_SWAP_ALWAYS));
}
void SwapData_Int32TypeWithNullInputSwapEndiannessToHost_ReturnsOK() {
void SwapData_Int32TypeWithNullInputSwapEndiannessToHost_ReturnsOK()
{
#if B_HOST_IS_LENDIAN
CHK(swap_data(B_INT32_TYPE, NULL, 4, B_SWAP_HOST_TO_LENDIAN) == B_OK);
CPPUNIT_ASSERT_EQUAL(B_OK, swap_data(B_INT32_TYPE, NULL, 4, B_SWAP_HOST_TO_LENDIAN));
#else
CHK(swap_data(B_INT32_TYPE, NULL, 4, B_SWAP_HOST_TO_BENDIAN) == B_OK);
CPPUNIT_ASSERT_EQUAL(B_OK, swap_data(B_INT32_TYPE, NULL, 4, B_SWAP_HOST_TO_BENDIAN));
#endif
}
void AlgorithmCheck() {
void AlgorithmCheck()
{
#define TEST(type, source, target) \
memcpy(target, source, sizeof(source)); \
for (int32 i = 0; i < 4; i++) { \
if (B_HOST_IS_LENDIAN) { \
swap_data(type, target, sizeof(target), B_SWAP_HOST_TO_LENDIAN); \
CHK(!memcmp(target, source, sizeof(source))); \
CPPUNIT_ASSERT_EQUAL(0, memcmp(target, source, sizeof(source))); \
swap_data(type, target, sizeof(target), B_SWAP_LENDIAN_TO_HOST); \
CHK(!memcmp(target, source, sizeof(source))); \
\
CPPUNIT_ASSERT_EQUAL(0, memcmp(target, source, sizeof(source))); \
\
swap_data(type, target, sizeof(target), B_SWAP_HOST_TO_BENDIAN); \
CHK(memcmp(target, source, sizeof(source))); \
CPPUNIT_ASSERT(memcmp(target, source, sizeof(source)) != 0); \
swap_data(type, target, sizeof(target), B_SWAP_BENDIAN_TO_HOST); \
CHK(!memcmp(target, source, sizeof(source))); \
CPPUNIT_ASSERT_EQUAL(0, memcmp(target, source, sizeof(source))); \
} else if (B_HOST_IS_BENDIAN) { \
swap_data(type, target, sizeof(target), B_SWAP_HOST_TO_BENDIAN); \
CHK(!memcmp(target, source, sizeof(source))); \
CPPUNIT_ASSERT_EQUAL(0, memcmp(target, source, sizeof(source))); \
swap_data(type, target, sizeof(target), B_SWAP_BENDIAN_TO_HOST); \
CHK(!memcmp(target, source, sizeof(source))); \
\
CPPUNIT_ASSERT_EQUAL(0, memcmp(target, source, sizeof(source))); \
\
swap_data(type, target, sizeof(target), B_SWAP_HOST_TO_LENDIAN); \
CHK(memcmp(target, source, sizeof(source))); \
CPPUNIT_ASSERT(memcmp(target, source, sizeof(source)) != 0); \
swap_data(type, target, sizeof(target), B_SWAP_LENDIAN_TO_HOST); \
CHK(!memcmp(target, source, sizeof(source))); \
CPPUNIT_ASSERT_EQUAL(0, memcmp(target, source, sizeof(source))); \
} \
\
\
swap_data(type, target, sizeof(target), B_SWAP_ALWAYS); \
CHK(memcmp(target, source, sizeof(source))); \
CPPUNIT_ASSERT(memcmp(target, source, sizeof(source)) != 0); \
swap_data(type, target, sizeof(target), B_SWAP_ALWAYS); \
CHK(!memcmp(target, source, sizeof(source))); \
CPPUNIT_ASSERT_EQUAL(0, memcmp(target, source, sizeof(source))); \
}
const uint64 kArray64[] = {0x0123456789abcdefULL, 0x1234, 0x5678000000000000ULL, 0x0};
@@ -233,8 +252,8 @@ public:
void IsTypeSwapped()
{
#define IS_SWAPPED(x) CHK(is_type_swapped(x))
#define NOT_SWAPPED(x) CHK(!is_type_swapped(x))
#define IS_SWAPPED(x) CPPUNIT_ASSERT_EQUAL(true, is_type_swapped(x))
#define NOT_SWAPPED(x) CPPUNIT_ASSERT_EQUAL(false, is_type_swapped(x))
NOT_SWAPPED(B_ANY_TYPE);
IS_SWAPPED(B_BOOL_TYPE);
+9 -14
View File
@@ -5,26 +5,20 @@
#include <DateTime.h>
#include <TestCase.h>
#include <TestSuiteAddon.h>
#include <TestUtils.h>
#include <cppunit/TestFixture.h>
#include <cppunit/TestSuite.h>
#include <cppunit/extensions/HelperMacros.h>
using CppUnit::TestFixture;
class DateTimeTest : public TestFixture {
class DateTimeTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(DateTimeTest);
CPPUNIT_TEST(SetToMinusOne_IsValidAndReturnsCorrectProperties);
CPPUNIT_TEST_SUITE_END();
public:
void SetToMinusOne_IsValidAndReturnsCorrectProperties();
};
void
DateTimeTest::SetToMinusOne_IsValidAndReturnsCorrectProperties()
{
void SetToMinusOne_IsValidAndReturnsCorrectProperties()
{
BDateTime dateTime;
// Should be just one second before epoch
@@ -37,7 +31,8 @@ DateTimeTest::SetToMinusOne_IsValidAndReturnsCorrectProperties()
CPPUNIT_ASSERT_EQUAL(31, dateTime.Date().Day());
CPPUNIT_ASSERT_EQUAL(12, dateTime.Date().Month());
CPPUNIT_ASSERT_EQUAL(1969, dateTime.Date().Year());
}
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(DateTimeTest, getTestSuiteName());
+31 -77
View File
@@ -2,87 +2,44 @@ SubDir HAIKU_TOP src tests kits support ;
AddSubDirSupportedPlatforms libbe_test ;
# Let Jam know where to find some of our source files
SEARCH_SOURCE += [ FDirName $(SUBDIR) barchivable ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) bautolock ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) blocker ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) bmemoryio ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) bstring ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) bblockcache ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) bstopwatch ] ;
UnitTestLib libsupporttest.so
: SupportKitTestAddon.cpp
ByteOrderTest.cpp
# BArchivable
ArchivableTest.cpp
BArchivableTester.cpp
FindInstantiationFuncTester.cpp
InstantiateObjectTester.cpp
LocalTestObject.cpp
ValidateInstantiationTester.cpp
# BAutolock
AutolockTest.cpp
AutolockLockerTest.cpp
AutolockLooperTest.cpp
# BDateTime
DateTimeTest.cpp
# BLocker (all in ./blocker)
LockerTest.cpp
BenaphoreLockCountTest1.cpp
ConcurrencyTest1.cpp
ConcurrencyTest2.cpp
ConstructionTest1.cpp
DestructionTest1.cpp
DestructionTest2.cpp
LockerTestCase.cpp
SemaphoreLockCountTest1.cpp
# BMemoryIO
MemoryIOTest.cpp
ConstTest.cpp
SeekTest.cpp
WriteTest.cpp
ReadTest.cpp
SetSizeTest.cpp
# BMallocIO
MallocIOTest.cpp
MallocSeekTest.cpp
MallocWriteTest.cpp
MallocBufferLengthTest.cpp
#BString
StringTest.cpp
StringConstructionTest.cpp
StringAccessTest.cpp
StringAssignTest.cpp
StringAppendTest.cpp
StringSubCopyTest.cpp
StringPrependTest.cpp
StringCaseTest.cpp
StringInsertTest.cpp
StringEscapeTest.cpp
StringRemoveTest.cpp
StringCompareTest.cpp
StringFormatAppendTest.cpp
StringCharAccessTest.cpp
StringSearchTest.cpp
StringReplaceTest.cpp
StringSplitTest.cpp
#BBlockCache
BlockCacheTest.cpp
BlockCacheExerciseTest.cpp
BlockCacheConcurrencyTest.cpp
ByteOrderTest.cpp
# BStopWatch
BStopWatchTest.cpp
DateTimeTest.cpp
LockerConcurrencyTest.cpp
LockerConstructionTest.cpp
LockerDestructionTest.cpp
LockerLockCountTest.cpp
MemoryIOTest.cpp
MallocIOTest.cpp
PointerListTest.cpp
StopWatchTest.cpp
StringAccessTest.cpp
StringAppendTest.cpp
StringAssignTest.cpp
StringCaseTest.cpp
StringCompareTest.cpp
StringConstructionTest.cpp
StringEscapeTest.cpp
StringFormatAppendTest.cpp
StringInsertTest.cpp
StringPrependTest.cpp
StringRemoveTest.cpp
StringReplaceTest.cpp
StringSearchTest.cpp
StringSplitTest.cpp
StringSubCopyTest.cpp
StringUTF8Test.cpp
: be [ TargetLibstdc++ ] libsupporttest_RemoteTestObject.so
;
@@ -90,8 +47,5 @@ UnitTestLib libsupporttest.so
UsePrivateHeaders support ;
SimpleTest compression_test : compression_test.cpp : be [ TargetLibsupc++ ] ;
SimpleTest string_utf8_tests : string_utf8_tests.cpp : be ;
SubInclude HAIKU_TOP src tests kits support barchivable ;
#SubInclude HAIKU_TOP src tests kits support bautolock ;
#SubInclude HAIKU_TOP src tests kits support blocker ;
SubInclude HAIKU_TOP src tests kits support remoteobjectdef ;
@@ -0,0 +1,239 @@
/*
* Copyright 2002-2026, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* tylerdauwalder
*/
#include <Locker.h>
#include <TestSuiteAddon.h>
#include <ThreadedTestCaller.h>
#include <cppunit/TestSuite.h>
#include <cppunit/extensions/HelperMacros.h>
#include <string.h>
static const int32 MAX_LOOP = 10000;
static const bigtime_t SNOOZE_TIME = 200000;
/**
* \brief Utility class to ensure a BLocker is released on destruction.
*/
class SafetyLock {
public:
SafetyLock(BLocker* lock) : fLocker(lock) {}
~SafetyLock() { if (fLocker != NULL) fLocker->Unlock(); }
private:
BLocker* fLocker;
};
/**
* \brief Test class for testing BLocker functionality.
*
* It tests use cases "Locking 1", "Locking 2", "Unlocking", "Is Locked",
* "Locking Thread" and "Count Locks".
*/
class LockerConcurrencyTest : public BThreadedTestCase {
public:
LockerConcurrencyTest(std::string name, bool benaphoreFlag);
virtual ~LockerConcurrencyTest();
virtual void setUp();
void SimpleLockingLoop();
void AcquireThread();
void TimeoutThread();
static CppUnit::Test* suite();
private:
void CheckLock(int expectedCount);
bool AcquireLock(int lockAttempt, bool firstAcquisition);
BLocker* fLocker;
bool fLockTestValue;
};
LockerConcurrencyTest::LockerConcurrencyTest(std::string name, bool benaphoreFlag)
:
BThreadedTestCase(name),
fLocker(new BLocker(benaphoreFlag)),
fLockTestValue(false)
{
}
LockerConcurrencyTest::~LockerConcurrencyTest()
{
delete fLocker;
}
void
LockerConcurrencyTest::CheckLock(int expectedCount)
{
CPPUNIT_ASSERT(fLocker->CountLockRequests() == expectedCount);
}
void
LockerConcurrencyTest::setUp()
{
fLockTestValue = false;
}
bool
LockerConcurrencyTest::AcquireLock(int lockAttempt, bool firstAcquisition)
{
bool timeoutLock;
if (firstAcquisition)
timeoutLock = ((lockAttempt % 2) == 1);
else
timeoutLock = (((lockAttempt / 2) % 2) == 1);
if (timeoutLock)
return fLocker->LockWithTimeout(1000000) == B_OK;
return fLocker->Lock();
}
/**
* This method is the core of the test. Each of the three threads
* run this method to perform the concurrency test. First, the
* SafetyLock class (see LockerTestCase.h) is used to make sure that
* the lock is released if an assertion happens. Then, each thread
* iterates MAXLOOP times through the main loop where the following
* actions are performed:
* - CheckLock() is used to show that the thread does not have
* the lock.
* - The thread acquires the lock.
* - The thread confirms that mutual exclusion is OK by testing
* lockTestValue.
* - The thread confirms the lock is held once by the thread.
* - The thread acquires the lock again.
* - The thread confirms the lock is held twice now by the thread.
* - The thread releases the lock once.
* - The thread confirms the lock is held once now.
* - The thread confirms that mutual exclusion is still OK by
* testing lockTestValue.
* - The thread releases the lock again.
* - The thread confirms that the lock is no longer held.
*/
void
LockerConcurrencyTest::SimpleLockingLoop()
{
SafetyLock theSafetyLock(fLocker);
for (int i = 0; i < MAX_LOOP; i++) {
CheckLock(0);
CPPUNIT_ASSERT(AcquireLock(i, true));
CPPUNIT_ASSERT(!fLockTestValue);
fLockTestValue = true;
CheckLock(1);
CPPUNIT_ASSERT(AcquireLock(i, false));
CheckLock(2);
fLocker->Unlock();
CheckLock(1);
CPPUNIT_ASSERT(fLockTestValue);
fLockTestValue = false;
fLocker->Unlock();
CheckLock(0);
}
}
/**
* This member function acquires the lock, sleeps for SNOOZE_TIME,
* releases the lock and then launches into the lock loop test.
*/
void
LockerConcurrencyTest::AcquireThread()
{
SafetyLock theSafetyLock(fLocker);
CPPUNIT_ASSERT(fLocker->Lock());
snooze(SNOOZE_TIME);
fLocker->Unlock();
SimpleLockingLoop();
}
/**
* This member function sleeps for a short time and then attempts to
* acquire the lock for SNOOZE_TIME/10 seconds. This acquisition
* should timeout. Then the locking loop is started.
*/
void
LockerConcurrencyTest::TimeoutThread()
{
SafetyLock theSafetyLock(fLocker);
snooze(SNOOZE_TIME / 2);
CPPUNIT_ASSERT(fLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT);
SimpleLockingLoop();
}
CppUnit::Test*
LockerConcurrencyTest::suite()
{
typedef BThreadedTestCaller<LockerConcurrencyTest> LockerConcurrencyTestCaller;
CppUnit::TestSuite* testSuite = new CppUnit::TestSuite("LockerConcurrencyTest");
// Benaphore
LockerConcurrencyTest* simpleBenaphore = new LockerConcurrencyTest("SimpleBenaphore", true);
LockerConcurrencyTestCaller* simpleBenaphoreCaller
= new LockerConcurrencyTestCaller("BLocker::Concurrency Test #1 (benaphore)", simpleBenaphore);
simpleBenaphoreCaller->addThread("A", &LockerConcurrencyTest::SimpleLockingLoop);
simpleBenaphoreCaller->addThread("B", &LockerConcurrencyTest::SimpleLockingLoop);
simpleBenaphoreCaller->addThread("C", &LockerConcurrencyTest::SimpleLockingLoop);
testSuite->addTest(simpleBenaphoreCaller);
// Semaphore
LockerConcurrencyTest* simpleSemaphore = new LockerConcurrencyTest("SimpleSemaphore", false);
LockerConcurrencyTestCaller* simpleSemaphoreCaller
= new LockerConcurrencyTestCaller("BLocker::Concurrency Test #1 (semaphore)", simpleSemaphore);
simpleSemaphoreCaller->addThread("A", &LockerConcurrencyTest::SimpleLockingLoop);
simpleSemaphoreCaller->addThread("B", &LockerConcurrencyTest::SimpleLockingLoop);
simpleSemaphoreCaller->addThread("C", &LockerConcurrencyTest::SimpleLockingLoop);
testSuite->addTest(simpleSemaphoreCaller);
// Benaphore
LockerConcurrencyTest* timeoutBenaphore = new LockerConcurrencyTest("TimeoutBenaphore", true);
LockerConcurrencyTestCaller* timeoutBenaphoreCaller
= new LockerConcurrencyTestCaller("BLocker::Concurrency Test #2 (benaphore)", timeoutBenaphore);
timeoutBenaphoreCaller->addThread("Acquire", &LockerConcurrencyTest::AcquireThread);
timeoutBenaphoreCaller->addThread("Timeout1", &LockerConcurrencyTest::TimeoutThread);
timeoutBenaphoreCaller->addThread("Timeout2", &LockerConcurrencyTest::TimeoutThread);
testSuite->addTest(timeoutBenaphoreCaller);
// Semaphore
LockerConcurrencyTest* timeoutSemaphore = new LockerConcurrencyTest("TimeoutSemaphore", false);
LockerConcurrencyTestCaller* timeoutSemaphoreCaller
= new LockerConcurrencyTestCaller("BLocker::Concurrency Test #2 (semaphore)", timeoutSemaphore);
timeoutSemaphoreCaller->addThread("Acquire", &LockerConcurrencyTest::AcquireThread);
timeoutSemaphoreCaller->addThread("Timeout1", &LockerConcurrencyTest::TimeoutThread);
timeoutSemaphoreCaller->addThread("Timeout2", &LockerConcurrencyTest::TimeoutThread);
testSuite->addTest(timeoutSemaphoreCaller);
return testSuite;
}
//CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(LockerConcurrencyTest, getTestSuiteName());
@@ -0,0 +1,102 @@
/*
* Copyright 2002-2026, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* tylerdauwalder
*/
#include <Locker.h>
#include <OS.h>
#include <TestSuiteAddon.h>
#include <ThreadedTestCaller.h>
#include <cppunit/TestSuite.h>
#include <cppunit/extensions/HelperMacros.h>
#include <string.h>
class LockerConstructionTest : public CppUnit::TestFixture {
public:
CPPUNIT_TEST_SUITE(LockerConstructionTest);
CPPUNIT_TEST(Constructor_Default_BenaphoreWithDefaultName);
CPPUNIT_TEST(Constructor_WithName_BenaphoreWithSpecifiedName);
CPPUNIT_TEST(Constructor_WithBenaphoreFalse_SemaphoreWithDefaultName);
CPPUNIT_TEST(Constructor_WithBenaphoreTrue_BenaphoreWithDefaultName);
CPPUNIT_TEST(Constructor_WithNameAndBenaphoreFalse_SemaphoreWithSpecifiedName);
CPPUNIT_TEST(Constructor_WithNameAndBenaphoreTrue_BenaphoreWithSpecifiedName);
CPPUNIT_TEST_SUITE_END();
private:
bool NameMatches(const char* name, BLocker* lockerArg)
{
sem_info theSemInfo;
CPPUNIT_ASSERT(get_sem_info(lockerArg->Sem(), &theSemInfo) == B_OK);
return strcmp(name, theSemInfo.name) == 0;
}
bool IsBenaphore(BLocker* lockerArg)
{
int32 semCount;
CPPUNIT_ASSERT(get_sem_count(lockerArg->Sem(), &semCount) == B_OK);
switch (semCount) {
case 0:
return true;
case 1:
return false;
default:
// Unexpected semaphore count
CPPUNIT_ASSERT(false);
break;
}
return false;
}
public:
void Constructor_Default_BenaphoreWithDefaultName()
{
BLocker locker;
CPPUNIT_ASSERT(NameMatches("some BLocker", &locker));
CPPUNIT_ASSERT(IsBenaphore(&locker));
}
void Constructor_WithName_BenaphoreWithSpecifiedName()
{
BLocker locker("test string");
CPPUNIT_ASSERT(NameMatches("test string", &locker));
CPPUNIT_ASSERT(IsBenaphore(&locker));
}
void Constructor_WithBenaphoreFalse_SemaphoreWithDefaultName()
{
BLocker locker(false);
CPPUNIT_ASSERT(NameMatches("some BLocker", &locker));
CPPUNIT_ASSERT(!IsBenaphore(&locker));
}
void Constructor_WithBenaphoreTrue_BenaphoreWithDefaultName()
{
BLocker locker(true);
CPPUNIT_ASSERT(NameMatches("some BLocker", &locker));
CPPUNIT_ASSERT(IsBenaphore(&locker));
}
void Constructor_WithNameAndBenaphoreFalse_SemaphoreWithSpecifiedName()
{
BLocker locker("test string", false);
CPPUNIT_ASSERT(NameMatches("test string", &locker));
CPPUNIT_ASSERT(!IsBenaphore(&locker));
}
void Constructor_WithNameAndBenaphoreTrue_BenaphoreWithSpecifiedName()
{
BLocker locker("test string", true);
CPPUNIT_ASSERT(NameMatches("test string", &locker));
CPPUNIT_ASSERT(IsBenaphore(&locker));
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(LockerConstructionTest, getTestSuiteName());
@@ -0,0 +1,212 @@
/*
* Copyright 2002-2026, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* tylerdauwalder
*/
#include <Locker.h>
#include <TestSuiteAddon.h>
#include <ThreadedTestCaller.h>
#include <cppunit/TestSuite.h>
#include <cppunit/extensions/HelperMacros.h>
#include <string.h>
static const bigtime_t SNOOZE_TIME = 200000;
/**
* \brief Class for testing BLocker functionality.
* It tests use cases "Destruction", "Locking 3" and "Locking 4".
*/
class LockerDestructionTest : public BThreadedTestCase {
public:
LockerDestructionTest(std::string name, bool isBenaphore);
virtual ~LockerDestructionTest();
void SimpleWaiterThread();
void SimpleDeleterThread();
void TimeoutWaiterThread();
void TimeoutDeleterThread();
static CppUnit::Test* suite();
private:
BLocker* fLocker;
};
LockerDestructionTest::LockerDestructionTest(std::string name, bool isBenaphore)
:
BThreadedTestCase(name),
fLocker(new BLocker(isBenaphore))
{
}
LockerDestructionTest::~LockerDestructionTest()
{
if (fLocker != NULL)
delete fLocker;
}
/**
* \brief Simple destruction tests
*
* The test works like the following:
* - the main thread acquires the lock
* - the second thread sleeps
* - the second thread then attempts to acquire the lock
* - the first thread releases the lock
* - at this time, the new thread acquires the lock and goes to sleep
* - the first thread attempts to acquire the lock
* - the second thread deletes the lock
* - the first thread is woken up indicating that the lock wasn't acquired.
*/
/**
* This method immediately acquires the lock, sleeps
* for SNOOZE_TIME and then releases the lock. It sleeps
* again for SNOOZE_TIME and then tries to re-acquire the
* lock. By this time, the other thread should have
* deleted the lock. This acquisition should fail.
*/
void
LockerDestructionTest::SimpleWaiterThread()
{
CPPUNIT_ASSERT(fLocker->Lock());
snooze(SNOOZE_TIME);
fLocker->Unlock();
snooze(SNOOZE_TIME);
CPPUNIT_ASSERT(!fLocker->Lock());
}
/**
* This method sleeps for SNOOZE_TIME and then acquires the lock.
* It sleeps again for 2*SNOOZE_TIME and then deletes the lock.
* This should wake up the other thread.
*/
void
LockerDestructionTest::SimpleDeleterThread()
{
BLocker* tmpLock;
snooze(SNOOZE_TIME);
CPPUNIT_ASSERT(fLocker->Lock());
snooze(SNOOZE_TIME);
snooze(SNOOZE_TIME);
tmpLock = fLocker;
fLocker = NULL;
delete tmpLock;
}
/**
* \brief Timeout destruction tests
*
* The test works like the following:
* - the main thread acquires the lock
* - it creates a new thread and sleeps
* - the new thread attempts to acquire the lock but times out
* - the new thread then attempts to acquire the lock again
* - before the new thread times out a second time, the first thread releases
* the lock
* - at this time, the new thread acquires the lock and goes to sleep
* - the first thread attempts to acquire the lock
* - the second thread deletes the lock
* - the first thread is woken up indicating that the lock wasn't acquired.
*/
/**
* This method immediately acquires the lock, sleeps
* for SNOOZE_TIME and then releases the lock. It sleeps
* again for SNOOZE_TIME and then tries to re-acquire the
* lock. By this time, the other thread should have
* deleted the lock. This acquisition should fail.
*/
void
LockerDestructionTest::TimeoutWaiterThread()
{
CPPUNIT_ASSERT(fLocker->LockWithTimeout(SNOOZE_TIME) == B_OK);
snooze(SNOOZE_TIME);
fLocker->Unlock();
snooze(SNOOZE_TIME);
// Should wake up with B_BAD_SEM_ID or B_BAD_VALUE since lock is deleted
CPPUNIT_ASSERT(fLocker->LockWithTimeout(SNOOZE_TIME * 10) == B_BAD_SEM_ID);
}
/**
* This method sleeps for SNOOZE_TIME/10 and then attempts to acquire
* the lock for SNOOZE_TIME/10 seconds. This acquisition will timeout
* because the other thread is holding the lock. Then it acquires the
* lock by using a larger timeout. It sleeps again for 2*SNOOZE_TIME and
* then deletes the lock. This should wake up the other thread.
*/
void
LockerDestructionTest::TimeoutDeleterThread()
{
BLocker* tmpLock;
snooze(SNOOZE_TIME / 10);
CPPUNIT_ASSERT(fLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT);
CPPUNIT_ASSERT(fLocker->LockWithTimeout(SNOOZE_TIME * 10) == B_OK);
snooze(SNOOZE_TIME);
snooze(SNOOZE_TIME);
tmpLock = fLocker;
fLocker = NULL;
delete tmpLock;
}
CppUnit::Test*
LockerDestructionTest::suite()
{
typedef BThreadedTestCaller<LockerDestructionTest> LockerDestructionTestCaller;
CppUnit::TestSuite* testSuite = new CppUnit::TestSuite("LockerDestructionTest");
// Benaphore
LockerDestructionTest* simpleBenaphore = new LockerDestructionTest("SimpleBenaphore", true);
LockerDestructionTestCaller* simpleBenaphoreCaller
= new LockerDestructionTestCaller("BLocker::Destruction Test #1 (benaphore)", simpleBenaphore);
simpleBenaphoreCaller->addThread("Waiter", &LockerDestructionTest::SimpleWaiterThread);
simpleBenaphoreCaller->addThread("Deleter", &LockerDestructionTest::SimpleDeleterThread);
testSuite->addTest(simpleBenaphoreCaller);
// Semaphore
LockerDestructionTest* simpleSemaphore = new LockerDestructionTest("SimpleSemaphore", false);
LockerDestructionTestCaller* simpleSemaphoreCaller
= new LockerDestructionTestCaller("BLocker::Destruction Test #1 (semaphore)", simpleSemaphore);
simpleSemaphoreCaller->addThread("Waiter", &LockerDestructionTest::SimpleWaiterThread);
simpleSemaphoreCaller->addThread("Deleter", &LockerDestructionTest::SimpleDeleterThread);
testSuite->addTest(simpleSemaphoreCaller);
// Benaphore
LockerDestructionTest* timeoutBenaphore = new LockerDestructionTest("TimeoutBenaphore", true);
LockerDestructionTestCaller* timeoutBenaphoreCaller
= new LockerDestructionTestCaller("BLocker::Destruction Test #2 (benaphore)", timeoutBenaphore);
timeoutBenaphoreCaller->addThread("Waiter", &LockerDestructionTest::TimeoutWaiterThread);
timeoutBenaphoreCaller->addThread("Deleter", &LockerDestructionTest::TimeoutDeleterThread);
testSuite->addTest(timeoutBenaphoreCaller);
// Semaphore
LockerDestructionTest* timeoutSemaphore = new LockerDestructionTest("TimeoutSemaphore", false);
LockerDestructionTestCaller* timeoutSemaphoreCaller
= new LockerDestructionTestCaller("BLocker::Destruction Test #2 (semaphore)", timeoutSemaphore);
timeoutSemaphoreCaller->addThread("Waiter", &LockerDestructionTest::TimeoutWaiterThread);
timeoutSemaphoreCaller->addThread("Deleter", &LockerDestructionTest::TimeoutDeleterThread);
testSuite->addTest(timeoutSemaphoreCaller);
return testSuite;
}
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(LockerDestructionTest, getTestSuiteName());
@@ -0,0 +1,236 @@
/*
* Copyright 2002-2026, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* tylerdauwalder
*/
/**
* This file implements a test class for testing BLocker functionality.
* It tests use cases "Count Lock Requests" for a benaphore style BLocker.
*
* The test works by:
* - checking the lock requests
* - acquiring the lock
* - checking the lock requests
* - staring a thread which times out acquiring the lock and then blocks
* again waiting for the lock
* - checking the lock requests
* - start a second thread which times out acquiring the lock and then blocks
* again waiting for the lock
* - checking the lock requests
* - release the lock
* - each blocked thread acquires the lock, checks the lock requests and releases
* the lock before terminating
* - the main thread checks the lock requests one last time
*/
#include <Locker.h>
#include <TestSuiteAddon.h>
#include <ThreadedTestCaller.h>
#include <cppunit/TestSuite.h>
#include <cppunit/extensions/HelperMacros.h>
#include <string.h>
static const bigtime_t SNOOZE_TIME = 100000;
/**
* \brief Utility class to ensure a BLocker is released on destruction.
*/
class SafetyLock {
public:
SafetyLock(BLocker* lock) : fLocker(lock) {}
~SafetyLock() { if (fLocker != NULL) fLocker->Unlock(); }
private:
BLocker* fLocker;
};
/**
* \brief Tests BLocker's CountLockRequests() functionality.
*/
class LockerLockCountTest : public BThreadedTestCase {
public:
LockerLockCountTest(std::string name, bool isBenaphore);
virtual ~LockerLockCountTest();
void TestThread1();
void TestThread2();
void TestThread3();
static CppUnit::Test* suite();
private:
bool CheckLockRequests(int expected);
BLocker* fLocker;
BLocker fThread2Lock;
BLocker fThread3Lock;
bool fIsBenaphore;
};
LockerLockCountTest::LockerLockCountTest(std::string name, bool isBenaphore)
:
BThreadedTestCase(name),
fLocker(new BLocker(isBenaphore)),
fThread2Lock("thread2Lock"),
fThread3Lock("thread3Lock"),
fIsBenaphore(isBenaphore)
{
}
LockerLockCountTest::~LockerLockCountTest()
{
delete fLocker;
}
bool
LockerLockCountTest::CheckLockRequests(int expected)
{
return fLocker->CountLockRequests() == expected;
}
/**
* \brief Main portion of the test
*
* This member function performs the main portion of the test.
* It first acquires thread2Lock and thread3Lock. This ensures
* that thread2 and thread3 will block until this thread wants
* them to start running. It then checks the lock count, acquires
* the lock and checks the lock count again. It unlocks each
* of the other two threads in turn and rechecks the lock count.
* Finally, it releases the lock and sleeps for a short while
* for the other two threads to finish. At the end, it checks
* the lock count on final time.
*/
void
LockerLockCountTest::TestThread1()
{
SafetyLock theSafetyLock1(fLocker);
SafetyLock theSafetyLock2(&fThread2Lock);
SafetyLock theSafetyLock3(&fThread3Lock);
CPPUNIT_ASSERT(fThread2Lock.Lock());
CPPUNIT_ASSERT(fThread3Lock.Lock());
// Initial request count varies by benaphore/semaphore
CPPUNIT_ASSERT(CheckLockRequests(fIsBenaphore ? 0 : 1));
CPPUNIT_ASSERT(fLocker->Lock());
CPPUNIT_ASSERT(CheckLockRequests(fIsBenaphore ? 1 : 2));
fThread2Lock.Unlock();
snooze(SNOOZE_TIME);
CPPUNIT_ASSERT(CheckLockRequests(fIsBenaphore ? 3 : 4));
fThread3Lock.Unlock();
snooze(SNOOZE_TIME);
CPPUNIT_ASSERT(CheckLockRequests(fIsBenaphore ? 5 : 6));
fLocker->Unlock();
snooze(SNOOZE_TIME);
CPPUNIT_ASSERT(CheckLockRequests(fIsBenaphore ? 2 : 3));
}
/**
* \brief Second thread of the test
*
* This member function defines the actions of the second thread of
* the test. First it sleeps for a short while and then blocks on
* the thread2Lock. When the first thread releases it, this thread
* begins its testing. It times out attempting to acquire the main
* lock and then blocks to acquire the lock. Once that lock is
* acquired, the lock count is checked before finishing this thread.
*/
void
LockerLockCountTest::TestThread2()
{
SafetyLock theSafetyLock1(fLocker);
snooze(SNOOZE_TIME / 10);
CPPUNIT_ASSERT(fThread2Lock.Lock());
CPPUNIT_ASSERT(fLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT);
CPPUNIT_ASSERT(fLocker->Lock());
int actual = fLocker->CountLockRequests();
if (fIsBenaphore)
CPPUNIT_ASSERT(actual == 3 || actual == 4);
else
CPPUNIT_ASSERT(actual == 4 || actual == 5);
fLocker->Unlock();
}
/**
* \brief Third thread of the test
*
* This member function defines the actions of the third thread of
* the test. First it sleeps for a short while and then blocks on
* the thread3Lock. When the first thread releases it, this thread
* begins its testing. It times out attempting to acquire the main
* lock and then blocks to acquire the lock. Once that lock is
* acquired, the lock count is checked before finishing this thread.
*/
void
LockerLockCountTest::TestThread3()
{
SafetyLock theSafetyLock1(fLocker);
snooze(SNOOZE_TIME / 10);
CPPUNIT_ASSERT(fThread3Lock.Lock());
CPPUNIT_ASSERT(fLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT);
CPPUNIT_ASSERT(fLocker->Lock());
int actual = fLocker->CountLockRequests();
if (fIsBenaphore)
CPPUNIT_ASSERT(actual == 3 || actual == 4);
else
CPPUNIT_ASSERT(actual == 4 || actual == 5);
fLocker->Unlock();
}
CppUnit::Test*
LockerLockCountTest::suite()
{
typedef BThreadedTestCaller<LockerLockCountTest> LockerLockCountTestCaller;
CppUnit::TestSuite* testSuite = new CppUnit::TestSuite("LockerLockCountTest");
// Benaphore test
LockerLockCountTest* benaphoreTest = new LockerLockCountTest("Benaphore", true);
LockerLockCountTestCaller* caller1
= new LockerLockCountTestCaller("BLocker::Benaphore Lock Count Test", benaphoreTest);
caller1->addThread("A", &LockerLockCountTest::TestThread1);
caller1->addThread("B", &LockerLockCountTest::TestThread2);
caller1->addThread("C", &LockerLockCountTest::TestThread3);
testSuite->addTest(caller1);
// Semaphore test
LockerLockCountTest* semaphoreTest = new LockerLockCountTest("Semaphore", false);
LockerLockCountTestCaller* caller2
= new LockerLockCountTestCaller("BLocker::Semaphore Lock Count Test", semaphoreTest);
caller2->addThread("A", &LockerLockCountTest::TestThread1);
caller2->addThread("B", &LockerLockCountTest::TestThread2);
caller2->addThread("C", &LockerLockCountTest::TestThread3);
testSuite->addTest(caller2);
return testSuite;
}
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(LockerLockCountTest, getTestSuiteName());
+143
View File
@@ -0,0 +1,143 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <DataIO.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <string.h>
class MallocIOTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(MallocIOTest);
CPPUNIT_TEST(BufferLength_Initial_IsZero);
CPPUNIT_TEST(BufferLength_AfterWrite_IsCorrect);
CPPUNIT_TEST(BufferLength_AfterSetSizeZero_IsZero);
CPPUNIT_TEST(BufferLength_AfterSetSizeIncrease_IsCorrectAndSeekEndIsCorrect);
CPPUNIT_TEST(BufferLength_AfterSetSizeDecrease_IsCorrectAndPositionIsUnchanged);
CPPUNIT_TEST(Seek_Set_ReturnsExpectedPosition);
CPPUNIT_TEST(Seek_Cur_ReturnsExpectedPosition);
CPPUNIT_TEST(Seek_End_ReturnsExpectedPosition);
CPPUNIT_TEST(Seek_EndNegative_ReturnsParsedPosition);
CPPUNIT_TEST(Seek_EndPositive_ReturnsPositionOutOfBounds);
CPPUNIT_TEST(Seek_SetNegative_ReturnsParsedPosition);
CPPUNIT_TEST(Write_Normal_ReturnsWrittenLength);
CPPUNIT_TEST(WriteAt_ZeroOffset_ReturnsWrittenLength);
CPPUNIT_TEST(WriteAt_LargeOffset_ReturnsWrittenLengthAndExpandsBuffer);
CPPUNIT_TEST_SUITE_END();
public:
void BufferLength_Initial_IsZero()
{
size_t bufLen = fMem.BufferLength();
CPPUNIT_ASSERT_EQUAL((size_t)0, bufLen);
}
void BufferLength_AfterWrite_IsCorrect()
{
char writeBuf[11] = "0123456789";
ssize_t size = fMem.Write(writeBuf, 10);
size_t bufLen = fMem.BufferLength();
CPPUNIT_ASSERT_EQUAL((size_t)10, bufLen);
CPPUNIT_ASSERT_EQUAL((ssize_t)10, size);
}
void BufferLength_AfterSetSizeZero_IsZero()
{
status_t error = fMem.SetSize(0);
size_t bufLen = fMem.BufferLength();
CPPUNIT_ASSERT_EQUAL((size_t)0, bufLen);
CPPUNIT_ASSERT_EQUAL(B_OK, error);
}
void BufferLength_AfterSetSizeIncrease_IsCorrectAndSeekEndIsCorrect()
{
status_t error = fMem.SetSize(200);
size_t bufLen = fMem.BufferLength();
off_t offset = fMem.Seek(0, SEEK_END);
CPPUNIT_ASSERT_EQUAL((size_t)200, bufLen);
CPPUNIT_ASSERT_EQUAL(B_OK, error);
CPPUNIT_ASSERT_EQUAL((off_t)200, offset);
}
void BufferLength_AfterSetSizeDecrease_IsCorrectAndPositionIsUnchanged()
{
fMem.SetSize(200);
off_t offset = fMem.Seek(0, SEEK_END);
status_t error = fMem.SetSize(100);
size_t bufLen = fMem.BufferLength();
CPPUNIT_ASSERT_EQUAL((size_t)100, bufLen);
CPPUNIT_ASSERT_EQUAL(offset, fMem.Position());
CPPUNIT_ASSERT_EQUAL(B_OK, error);
}
void Seek_Set_ReturnsExpectedPosition()
{
off_t err = fMem.Seek(3, SEEK_SET);
CPPUNIT_ASSERT_EQUAL((off_t)3, err);
}
void Seek_Cur_ReturnsExpectedPosition()
{
off_t err = fMem.Seek(3, SEEK_CUR);
CPPUNIT_ASSERT_EQUAL((off_t)3, err);
}
void Seek_End_ReturnsExpectedPosition()
{
off_t err = fMem.Seek(0, SEEK_END);
CPPUNIT_ASSERT_EQUAL((off_t)0, err);
}
void Seek_EndNegative_ReturnsParsedPosition()
{
off_t err = fMem.Seek(-5, SEEK_END);
CPPUNIT_ASSERT_EQUAL((off_t)-5, err);
}
void Seek_EndPositive_ReturnsPositionOutOfBounds()
{
off_t err = fMem.Seek(5, SEEK_END);
CPPUNIT_ASSERT_EQUAL((off_t)5, err);
}
void Seek_SetNegative_ReturnsParsedPosition()
{
off_t err = fMem.Seek(-20, SEEK_SET);
CPPUNIT_ASSERT_EQUAL((off_t)-20, err);
}
void Write_Normal_ReturnsWrittenLength()
{
const char* writeBuf = "ABCDEFG";
ssize_t err = fMem.Write(writeBuf, 7);
CPPUNIT_ASSERT_EQUAL((ssize_t)7, err);
}
void WriteAt_ZeroOffset_ReturnsWrittenLength()
{
const char* writeBuf = "ABCDEFG";
ssize_t err = fMem.WriteAt(0, writeBuf, 4);
CPPUNIT_ASSERT_EQUAL((ssize_t)4, err);
}
void WriteAt_LargeOffset_ReturnsWrittenLengthAndExpandsBuffer()
{
const char* writeBuf = "ABCDEFG";
ssize_t err = fMem.WriteAt(34, writeBuf, 256);
CPPUNIT_ASSERT_EQUAL((ssize_t)256, err);
}
private:
BMallocIO fMem;
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(MallocIOTest, getTestSuiteName());
+223
View File
@@ -0,0 +1,223 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <DataIO.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <string.h>
class MemoryIOTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(MemoryIOTest);
CPPUNIT_TEST(ReadOnlyMemory_Write_ReturnsNotAllowed);
CPPUNIT_TEST(ReadOnlyMemory_WriteAt_ReturnsNotAllowed);
CPPUNIT_TEST(ReadOnlyMemory_SetSize_Smaller_ReturnsNotAllowed);
CPPUNIT_TEST(ReadOnlyMemory_SetSize_Larger_ReturnsNotAllowed);
CPPUNIT_TEST(Read_Normal_Succeeds);
CPPUNIT_TEST(ReadAt_OutOfBounds_ReturnsZero);
CPPUNIT_TEST(Read_AtEOF_ReturnsZero);
CPPUNIT_TEST(Seek_Set_ReturnsExpectedPosition);
CPPUNIT_TEST(Seek_Cur_ReturnsExpectedPosition);
CPPUNIT_TEST(Seek_End_ReturnsExpectedPosition);
CPPUNIT_TEST(Seek_EndNegative_ReturnsParsedPosition);
CPPUNIT_TEST(Seek_EndPositive_ReturnsPositionOutOfBounds);
CPPUNIT_TEST(SetSize_Smaller_TruncatesAndReturnsOK);
CPPUNIT_TEST(SetSize_Same_ReturnsOK);
CPPUNIT_TEST(SetSize_Larger_ReturnsError);
CPPUNIT_TEST(Write_Normal_Succeeds);
CPPUNIT_TEST(WriteAt_Normal_Succeeds);
CPPUNIT_TEST(WriteAt_Truncated_Succeeds);
CPPUNIT_TEST(WriteAt_NegativeOffset_ReturnsBadValue);
CPPUNIT_TEST_SUITE_END();
public:
void setUp()
{
fBufferSize = 20;
fBuffer = new char[fBufferSize];
memcpy(fBuffer, "0123456789ABCDEFGHI", fBufferSize);
fReadBuffer = new char[10];
memset(fReadBuffer, 0, 10);
fMem = new BMemoryIO(fBuffer, fBufferSize);
fReadOnlyMem = new BMemoryIO((const void*)fBuffer, fBufferSize);
}
void tearDown()
{
delete fReadOnlyMem;
delete fMem;
delete[] fReadBuffer;
delete[] fBuffer;
}
void ReadOnlyMemory_Write_ReturnsNotAllowed()
{
status_t err = fReadOnlyMem->Write(fReadBuffer, 3);
CPPUNIT_ASSERT_EQUAL(B_NOT_ALLOWED, err);
}
void ReadOnlyMemory_WriteAt_ReturnsNotAllowed()
{
const char* writeBuf = "ABCDEFG";
off_t pos = fReadOnlyMem->Position();
status_t err = fReadOnlyMem->WriteAt(2, writeBuf, 1);
CPPUNIT_ASSERT_EQUAL(B_NOT_ALLOWED, err);
CPPUNIT_ASSERT_EQUAL(pos, fReadOnlyMem->Position());
}
void ReadOnlyMemory_SetSize_Smaller_ReturnsNotAllowed()
{
status_t err = fReadOnlyMem->SetSize(4);
CPPUNIT_ASSERT_EQUAL(B_NOT_ALLOWED, err);
}
void ReadOnlyMemory_SetSize_Larger_ReturnsNotAllowed()
{
status_t err = fReadOnlyMem->SetSize(40);
CPPUNIT_ASSERT_EQUAL(B_NOT_ALLOWED, err);
}
void Read_Normal_Succeeds()
{
off_t pos = fMem->Position();
ssize_t err = fMem->Read(fReadBuffer, 10);
CPPUNIT_ASSERT_EQUAL((ssize_t)10, err);
CPPUNIT_ASSERT(strncmp(fReadBuffer, fBuffer, 10) == 0);
CPPUNIT_ASSERT_EQUAL(pos + err, fMem->Position());
}
void ReadAt_OutOfBounds_ReturnsZero()
{
off_t pos = fMem->Position();
ssize_t err = fMem->ReadAt(30, fReadBuffer, 10);
CPPUNIT_ASSERT_EQUAL((ssize_t)0, err);
CPPUNIT_ASSERT_EQUAL(pos, fMem->Position());
}
void Read_AtEOF_ReturnsZero()
{
off_t pos = fMem->Seek(0, SEEK_END);
ssize_t err = fMem->Read(fReadBuffer, 10);
CPPUNIT_ASSERT_EQUAL((ssize_t)0, err);
CPPUNIT_ASSERT_EQUAL(pos, fMem->Position());
}
void Seek_Set_ReturnsExpectedPosition()
{
off_t err = fMem->Seek(3, SEEK_SET);
CPPUNIT_ASSERT_EQUAL((off_t)3, err);
}
void Seek_Cur_ReturnsExpectedPosition()
{
off_t err = fMem->Seek(3, SEEK_CUR);
CPPUNIT_ASSERT_EQUAL((off_t)3, err);
}
void Seek_End_ReturnsExpectedPosition()
{
off_t err = fMem->Seek(0, SEEK_END);
CPPUNIT_ASSERT_EQUAL((off_t)fBufferSize, err);
}
void Seek_EndNegative_ReturnsParsedPosition()
{
off_t err = fMem->Seek(-5, SEEK_END);
CPPUNIT_ASSERT_EQUAL((off_t)fBufferSize - 5, err);
}
void Seek_EndPositive_ReturnsPositionOutOfBounds()
{
off_t err = fMem->Seek(5, SEEK_END);
CPPUNIT_ASSERT_EQUAL((off_t)fBufferSize + 5, err);
}
void SetSize_Smaller_TruncatesAndReturnsOK()
{
BMemoryIO mem(fBuffer, 10);
status_t err = mem.SetSize(5);
CPPUNIT_ASSERT_EQUAL(B_OK, err);
CPPUNIT_ASSERT_EQUAL((off_t)5, mem.Seek(0, SEEK_END));
ssize_t size = mem.WriteAt(10, fReadBuffer, 3);
CPPUNIT_ASSERT_EQUAL((ssize_t)0, size);
}
void SetSize_Same_ReturnsOK()
{
BMemoryIO mem(fBuffer, 10);
status_t err = mem.SetSize(10);
CPPUNIT_ASSERT_EQUAL(B_OK, err);
CPPUNIT_ASSERT_EQUAL((off_t)10, mem.Seek(0, SEEK_END));
ssize_t size = mem.WriteAt(5, fReadBuffer, 6);
CPPUNIT_ASSERT_EQUAL((ssize_t)5, size);
}
void SetSize_Larger_ReturnsError()
{
BMemoryIO mem(fBuffer, 10);
status_t err = mem.SetSize(20);
CPPUNIT_ASSERT_EQUAL(B_ERROR, err);
}
void Write_Normal_Succeeds()
{
const char* writeBuf = "ABCDEFG";
off_t pos = fMem->Position();
ssize_t err = fMem->Write(writeBuf, 7);
CPPUNIT_ASSERT_EQUAL((ssize_t)7, err);
CPPUNIT_ASSERT(strncmp(writeBuf, fBuffer, 7) == 0);
CPPUNIT_ASSERT_EQUAL(pos + err, fMem->Position());
}
void WriteAt_Normal_Succeeds()
{
const char* writeBuf = "ABCDEFG";
off_t pos = fMem->Position();
ssize_t err = fMem->WriteAt(3, writeBuf, 2);
CPPUNIT_ASSERT_EQUAL((ssize_t)2, err);
CPPUNIT_ASSERT(strncmp(fBuffer + 3, writeBuf, 2) == 0);
CPPUNIT_ASSERT_EQUAL(pos, fMem->Position());
}
void WriteAt_Truncated_Succeeds()
{
const char* writeBuf = "ABCDEFG";
off_t pos = fMem->Position();
ssize_t err = fMem->WriteAt(fBufferSize - 1, writeBuf, 5);
CPPUNIT_ASSERT_EQUAL((ssize_t)1, err);
CPPUNIT_ASSERT(strncmp(fBuffer + fBufferSize - 1, writeBuf, 1) == 0);
CPPUNIT_ASSERT_EQUAL(pos, fMem->Position());
}
void WriteAt_NegativeOffset_ReturnsBadValue()
{
const char* writeBuf = "ABCDEFG";
off_t pos = fMem->Position();
ssize_t err = fMem->WriteAt(-10, writeBuf, 5);
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, err);
CPPUNIT_ASSERT_EQUAL(pos, fMem->Position());
}
private:
char* fBuffer;
size_t fBufferSize;
char* fReadBuffer;
BMemoryIO* fMem;
BMemoryIO* fReadOnlyMem;
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(MemoryIOTest, getTestSuiteName());
+507
View File
@@ -0,0 +1,507 @@
/*
* Copyright 2004, Michael Pfeiffer ([email protected]).
* Copyright 2021, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ObjectList.h>
#include <StopWatch.h>
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class Item {
public:
Item() { Init(); }
Item(const Item& item)
:
fValue(item.fValue)
{
Init();
}
Item(int value)
:
fValue(value)
{
Init();
}
virtual ~Item() { fInstances--; }
int Value() const { return fValue; }
bool Equals(const Item* item) const { return item != NULL && fValue == item->fValue; }
static int GetNumberOfInstances() { return fInstances; }
void Print() const { fprintf(stderr, "[%d] %d", fID, fValue); }
static int Compare(const void* a, const void* b)
{
const Item* itemA = (const Item*)a;
const Item* itemB = (const Item*)b;
if (itemA == itemB)
return 0;
if (itemA == NULL)
return -1;
if (itemB == NULL)
return 1;
return itemA->Value() - itemB->Value();
}
private:
void Init()
{
fID = fNextID++;
fInstances++;
}
int fID; // unique id for each created Item
int fValue; // the value of the item
static int fNextID;
static int fInstances;
};
int Item::fNextID = 0;
int Item::fInstances = 0;
static void* gData = NULL;
static int
CompareWithData(const void* a, const void* b, void* data)
{
CPPUNIT_ASSERT(gData == data);
return Item::Compare(a, b);
}
static void*
CopyTo(void* item, void* data)
{
_PointerList_* list = (_PointerList_*)data;
list->AddItem(item);
return NULL;
}
static void*
FirstItem(void* item, void* data)
{
return item;
}
class PointerListTest : public CppUnit::TestFixture {
public:
CPPUNIT_TEST_SUITE(PointerListTest);
CPPUNIT_TEST(Lifecycle_AddAndRemove_InstancesMatch);
CPPUNIT_TEST(Owning_ConstructorAndClone_InstancesMatch);
CPPUNIT_TEST(SortItems_RandomValues_IsSorted);
CPPUNIT_TEST(HSortItems_RandomValues_IsHSorted);
CPPUNIT_TEST(SortItems_WithState_IsSorted);
CPPUNIT_TEST(EachElement_IterateAll_ValidItems);
CPPUNIT_TEST(BinarySearch_Search_ReturnsCorrectResult);
CPPUNIT_TEST(BinarySearchIndex_Search_ReturnsCorrectIndex);
CPPUNIT_TEST(ReplaceItem_InvalidIndex_ReturnsFalse);
CPPUNIT_TEST(SortItems_RepeatedCalls_NoCrash);
CPPUNIT_TEST_SUITE_END();
void Lifecycle_AddAndRemove_InstancesMatch();
void Owning_ConstructorAndClone_InstancesMatch();
void SortItems_RandomValues_IsSorted();
void HSortItems_RandomValues_IsHSorted();
void SortItems_WithState_IsSorted();
void EachElement_IterateAll_ValidItems();
void BinarySearch_Search_ReturnsCorrectResult();
void BinarySearchIndex_Search_ReturnsCorrectIndex();
void ReplaceItem_InvalidIndex_ReturnsFalse();
void SortItems_RepeatedCalls_NoCrash();
private:
Item* CreateItem();
void Initialize(_PointerList_& list, int size);
void MakeEmpty(_PointerList_& list);
bool Equals(const _PointerList_& list1, const _PointerList_& list2);
bool IsSorted(const _PointerList_& list, int32 n);
bool IsSorted(const _PointerList_& list) { return IsSorted(list, list.CountItems()); }
bool IsHSorted(const _PointerList_& list) { return IsSorted(list, list.CountItems() - 1); }
int IndexOf(const _PointerList_& list, int value);
};
#define MAX_ID 10000
#define NOT_USED_ID -1
#define NOT_USED_ID_HIGH (MAX_ID + 1)
Item*
PointerListTest::CreateItem()
{
return new Item(rand() % (MAX_ID + 1));
}
void
PointerListTest::Initialize(_PointerList_& list, int size)
{
for (int32 i = 0; i < size; i++)
list.AddItem(CreateItem());
}
void
PointerListTest::MakeEmpty(_PointerList_& list)
{
const int32 n = list.CountItems();
for (int32 i = 0; i < n; i++) {
Item* item = (Item*)list.ItemAt(i);
delete item;
}
list.MakeEmpty();
}
bool
PointerListTest::Equals(const _PointerList_& list1, const _PointerList_& list2)
{
const int32 n = list1.CountItems();
if (n != list2.CountItems())
return false;
for (int32 i = 0; i < n; i++) {
Item* item1 = (Item*)list1.ItemAt(i);
Item* item2 = (Item*)list2.ItemAt(i);
if (item1 == item2)
continue;
if (item1 == NULL || !item1->Equals(item2))
return false;
}
return true;
}
bool
PointerListTest::IsSorted(const _PointerList_& list, int32 n)
{
int prevValue = -1;
for (int32 i = 0; i < n; i++) {
Item* item = (Item*)list.ItemAt(i);
CPPUNIT_ASSERT(item != NULL);
int value = item->Value();
if (value < prevValue)
return false;
prevValue = value;
}
return true;
}
int
PointerListTest::IndexOf(const _PointerList_& list, int value)
{
int n = list.CountItems();
for (int32 i = 0; i < n; i++) {
Item* item = (Item*)list.ItemAt(i);
if (item != NULL && item->Value() == value)
return i;
}
return -1;
}
void
PointerListTest::Lifecycle_AddAndRemove_InstancesMatch()
{
_PointerList_ list;
int numberOfInstances = Item::GetNumberOfInstances();
CPPUNIT_ASSERT(list.CountItems() == 0);
Initialize(list, 10);
CPPUNIT_ASSERT(list.CountItems() == 10);
int newInstances = Item::GetNumberOfInstances() - numberOfInstances;
CPPUNIT_ASSERT_EQUAL(10, newInstances);
numberOfInstances = Item::GetNumberOfInstances();
MakeEmpty(list);
int deletedInstances = numberOfInstances - Item::GetNumberOfInstances();
CPPUNIT_ASSERT_EQUAL(10, deletedInstances);
}
void
PointerListTest::Owning_ConstructorAndClone_InstancesMatch()
{
_PointerList_ list(10, true);
CPPUNIT_ASSERT(list.CountItems() == 0);
int numberOfInstances = Item::GetNumberOfInstances();
Initialize(list, 10);
CPPUNIT_ASSERT(list.CountItems() == 10);
CPPUNIT_ASSERT_EQUAL(10, Item::GetNumberOfInstances() - numberOfInstances);
_PointerList_* clone = new _PointerList_(list);
CPPUNIT_ASSERT_EQUAL(10, Item::GetNumberOfInstances() - numberOfInstances);
MakeEmpty(list);
CPPUNIT_ASSERT_EQUAL(0, Item::GetNumberOfInstances() - numberOfInstances);
delete clone;
CPPUNIT_ASSERT_EQUAL(0, Item::GetNumberOfInstances() - numberOfInstances);
}
void
PointerListTest::SortItems_RandomValues_IsSorted()
{
for (int i = 0; i < 10; i++) {
_PointerList_ list;
Initialize(list, i);
list.SortItems(Item::Compare);
CPPUNIT_ASSERT(IsSorted(list));
MakeEmpty(list);
}
}
void
PointerListTest::HSortItems_RandomValues_IsHSorted()
{
for (int i = 1; i < 10; i++) {
_PointerList_ list;
Initialize(list, i);
_PointerList_ clone(list);
int lastItem = clone.CountItems() - 1;
Item* item = (Item*)clone.ItemAt(0);
clone.HSortItems(Item::Compare);
CPPUNIT_ASSERT(IsHSorted(clone));
CPPUNIT_ASSERT_EQUAL(item, (Item*)clone.ItemAt(lastItem));
MakeEmpty(list);
}
}
void
PointerListTest::SortItems_WithState_IsSorted()
{
gData = (void*)0x4711;
// The original test used FROM=10000 TO=10000, which is just one iteration.
for (int i = 10; i <= 20; i++) {
_PointerList_ list;
Initialize(list, i);
_PointerList_ clone(list);
CPPUNIT_ASSERT(Equals(list, clone));
list.SortItems(CompareWithData, gData);
CPPUNIT_ASSERT(IsSorted(list));
list.SortItems(CompareWithData, gData);
CPPUNIT_ASSERT(IsSorted(list));
int lastItem = clone.CountItems() - 1;
bool hasItems = clone.CountItems() > 0;
Item* item = NULL;
if (hasItems)
item = (Item*)clone.ItemAt(0);
clone.HSortItems(CompareWithData, gData);
CPPUNIT_ASSERT(IsHSorted(clone));
CPPUNIT_ASSERT(!hasItems || item == (Item*)clone.ItemAt(lastItem));
MakeEmpty(list);
}
}
void
PointerListTest::EachElement_IterateAll_ValidItems()
{
_PointerList_ list;
Initialize(list, 10);
CPPUNIT_ASSERT_EQUAL((int32)10, list.CountItems());
_PointerList_ clone;
list.EachElement(CopyTo, &clone);
CPPUNIT_ASSERT_EQUAL(list.CountItems(), clone.CountItems());
void* item = list.EachElement(FirstItem, NULL);
CPPUNIT_ASSERT(item == list.ItemAt(0));
MakeEmpty(list);
}
void
PointerListTest::BinarySearch_Search_ReturnsCorrectResult()
{
_PointerList_ list;
Initialize(list, 10);
list.SortItems(Item::Compare);
CPPUNIT_ASSERT(IsSorted(list));
gData = (void*)0x4711;
Item notInListLow(NOT_USED_ID);
Item notInListHigh(NOT_USED_ID_HIGH);
for (int32 i = 0; i < 10; i++) {
Item* item = (Item*)list.ItemAt(i);
CPPUNIT_ASSERT(item != NULL);
Item* found = (Item*)list.BinarySearch(item, Item::Compare);
CPPUNIT_ASSERT(item->Equals(found));
found = (Item*)list.BinarySearch(item, CompareWithData, gData);
CPPUNIT_ASSERT(item->Equals(found));
found = (Item*)list.BinarySearch(&notInListLow, Item::Compare);
CPPUNIT_ASSERT(found == NULL);
found = (Item*)list.BinarySearch(&notInListHigh, Item::Compare);
CPPUNIT_ASSERT(found == NULL);
}
MakeEmpty(list);
}
class Value {
public:
Value(int value) : value(value) {}
int value;
};
static int
ValuePredicate(const void* _item, void* _value)
{
const Item* item = (const Item*)_item;
Value* value = (Value*)_value;
return item->Value() - value->value;
}
void
PointerListTest::BinarySearchIndex_Search_ReturnsCorrectIndex()
{
_PointerList_ list;
Initialize(list, 10);
list.SortItems(Item::Compare);
CPPUNIT_ASSERT(IsSorted(list));
Item notInListLow(NOT_USED_ID);
Item notInListHigh(NOT_USED_ID_HIGH);
gData = (void*)0x4711;
for (int32 i = 0; i < 10; i++) {
Item* item = (Item*)list.ItemAt(i);
CPPUNIT_ASSERT(item != NULL);
Value value(item->Value());
int index = IndexOf(list, item->Value());
int searchIndex;
searchIndex = list.BinarySearchIndex(item, Item::Compare);
CPPUNIT_ASSERT_EQUAL(index, searchIndex);
searchIndex = list.BinarySearchIndex(item, CompareWithData, gData);
CPPUNIT_ASSERT_EQUAL(index, searchIndex);
searchIndex = list.BinarySearchIndexByPredicate(&value, ValuePredicate);
CPPUNIT_ASSERT_EQUAL(index, searchIndex);
// notInListLow
searchIndex = list.BinarySearchIndex(&notInListLow, Item::Compare);
CPPUNIT_ASSERT_EQUAL(-1, searchIndex);
// notInListHigh
searchIndex = list.BinarySearchIndex(&notInListHigh, Item::Compare);
CPPUNIT_ASSERT_EQUAL(-(list.CountItems() + 1), searchIndex);
}
MakeEmpty(list);
for (int i = 0; i < 3; i++)
list.AddItem(new Item(2 * i));
Item notInList(3);
CPPUNIT_ASSERT_EQUAL(-1, IndexOf(list, 3));
int index = list.BinarySearchIndex(&notInList, Item::Compare);
CPPUNIT_ASSERT_EQUAL(-3, index);
MakeEmpty(list);
}
void
PointerListTest::ReplaceItem_InvalidIndex_ReturnsFalse()
{
_PointerList_ list;
Initialize(list, 10);
// R5 crashes on many NULL parameters, so we only test what's safe or expected
// to fail in Haiku
CPPUNIT_ASSERT(!list.ReplaceItem(-1, NULL));
CPPUNIT_ASSERT(!list.ReplaceItem(100, NULL));
MakeEmpty(list);
}
static int
SortItemTestPositive(const void* item1, const void* item2)
{
return 1;
}
static int
SortItemTestNegative(const void* item1, const void* item2)
{
return -1;
}
static int
SortItemTestEqual(const void* item1, const void* item2)
{
return 0;
}
void
PointerListTest::SortItems_RepeatedCalls_NoCrash()
{
_PointerList_ list;
for (int i = 0; i < 16; i++) { // FIXME: crashes at i = 16???
list.AddItem(new Item(i));
list.SortItems(SortItemTestPositive);
list.SortItems(SortItemTestNegative);
list.SortItems(SortItemTestEqual);
}
MakeEmpty(list);
}
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(PointerListTest, getTestSuiteName());
+150
View File
@@ -0,0 +1,150 @@
/*
* Copyright 2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <cstring>
#include <unistd.h>
#include <StopWatch.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/TestSuite.h>
#include <cppunit/extensions/HelperMacros.h>
class StopWatchTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StopWatchTest);
CPPUNIT_TEST(NameWithNull_ReturnsEmptyString);
CPPUNIT_TEST(NameWithValidString_ReturnsSetName);
CPPUNIT_TEST(ElapsedTimeAfterDelay_Increases);
CPPUNIT_TEST(ElapsedTimeWhenSuspended_DoesNotChange);
CPPUNIT_TEST(LapWhenRunning_ReturnsIncreasingTime);
CPPUNIT_TEST(LapWhenExceedsMax_StillReturnsValidTime);
CPPUNIT_TEST(LapWhenSuspended_ReturnsZero);
CPPUNIT_TEST(ResetAfterRunning_ClearsElapsedTime);
CPPUNIT_TEST(ElapsedTimeAfterMultipleSuspendResume_OnlyCountsActivePeriods);
CPPUNIT_TEST_SUITE_END();
public:
void NameWithNull_ReturnsEmptyString()
{
BStopWatch sw(NULL, true);
const char* name = sw.Name();
CPPUNIT_ASSERT(strcmp(name, "") == 0);
}
void NameWithValidString_ReturnsSetName()
{
BStopWatch sw("mywatch", true);
const char* name = sw.Name();
CPPUNIT_ASSERT(strcmp(name, "mywatch") == 0);
}
void ElapsedTimeAfterDelay_Increases()
{
BStopWatch sw("et", true);
bigtime_t t1 = sw.ElapsedTime();
CPPUNIT_ASSERT(t1 >= 0);
usleep(10000);
bigtime_t t2 = sw.ElapsedTime();
CPPUNIT_ASSERT(t2 > 0);
CPPUNIT_ASSERT(t2 > t1);
}
void ElapsedTimeWhenSuspended_DoesNotChange()
{
BStopWatch sw("sr", true);
usleep(5000);
sw.Suspend();
bigtime_t t1 = sw.ElapsedTime();
usleep(10000);
bigtime_t t2 = sw.ElapsedTime();
CPPUNIT_ASSERT_EQUAL(t1, t2);
sw.Resume();
usleep(5000);
bigtime_t t3 = sw.ElapsedTime();
CPPUNIT_ASSERT(t3 > t2);
}
void LapWhenRunning_ReturnsIncreasingTime()
{
BStopWatch sw("lap", true);
usleep(2000);
bigtime_t l1 = sw.Lap();
usleep(2000);
bigtime_t l2 = sw.Lap();
CPPUNIT_ASSERT(l2 > l1);
}
void LapWhenExceedsMax_StillReturnsValidTime()
{
BStopWatch sw("lapoverflow", true);
for (int i = 0; i < 12; i++)
sw.Lap();
CPPUNIT_ASSERT(sw.Lap() > 0);
}
void LapWhenSuspended_ReturnsZero()
{
BStopWatch sw("lap2", true);
sw.Suspend();
bigtime_t lapTime = sw.Lap();
CPPUNIT_ASSERT_EQUAL((bigtime_t)0, lapTime);
}
void ResetAfterRunning_ClearsElapsedTime()
{
BStopWatch sw("reset", true);
usleep(50000);
sw.Lap();
bigtime_t beforeReset = sw.ElapsedTime();
CPPUNIT_ASSERT(beforeReset >= 50000);
sw.Reset();
CPPUNIT_ASSERT(sw.ElapsedTime() < 5000);
}
void ElapsedTimeAfterMultipleSuspendResume_OnlyCountsActivePeriods()
{
BStopWatch sw("multi", true);
usleep(2000);
sw.Suspend();
usleep(2000);
sw.Resume();
usleep(2000);
sw.Suspend();
usleep(2000);
sw.Resume();
usleep(2000);
sw.Suspend();
bigtime_t elapsed = sw.ElapsedTime();
CPPUNIT_ASSERT(elapsed >= 6000);
CPPUNIT_ASSERT(elapsed < 7000);
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StopWatchTest, getTestSuiteName());
+138
View File
@@ -0,0 +1,138 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <UTF8.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringAccessTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringAccessTest);
CPPUNIT_TEST(OperatorBracket_ValidIndex_ReturnsChar);
CPPUNIT_TEST(SetByteAt_ValidIndex_ModifiesChar);
CPPUNIT_TEST(ByteAt_ValidAndInvalidIndex_ReturnsCharOrZero);
CPPUNIT_TEST(CountChars_WithEllipsis_ReturnsCorrectCount);
CPPUNIT_TEST(CountChars_Ascii_ReturnsCorrectCount);
CPPUNIT_TEST(CountChars_Combination_ReturnsCorrectCount);
CPPUNIT_TEST(Access_EmptyString_ReturnsZeros);
CPPUNIT_TEST(CountChars_InvalidUtf8_ReturnsCorrectCount);
CPPUNIT_TEST(LockBuffer_WithCapacity_ReturnsValidPointer);
CPPUNIT_TEST(UnlockBuffer_WithLength_TruncatesString);
CPPUNIT_TEST(LockBuffer_EmptyString_ReturnsValidPointer);
#ifndef TEST_R5
CPPUNIT_TEST(LockBuffer_ZeroLength_DoesNotCrash);
#endif
CPPUNIT_TEST_SUITE_END();
public:
void OperatorBracket_ValidIndex_ReturnsChar()
{
BString string("A simple string");
CPPUNIT_ASSERT_EQUAL('A', string[0]);
CPPUNIT_ASSERT_EQUAL(' ', string[1]);
}
void SetByteAt_ValidIndex_ModifiesChar()
{
BString string("A simple string");
string.SetByteAt(0, 'a');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "a simple string"));
}
void ByteAt_ValidAndInvalidIndex_ReturnsCharOrZero()
{
BString string("A simple string");
CPPUNIT_ASSERT_EQUAL(0, string.ByteAt(-10));
CPPUNIT_ASSERT_EQUAL(0, string.ByteAt(200));
CPPUNIT_ASSERT_EQUAL(' ', string.ByteAt(1));
CPPUNIT_ASSERT_EQUAL('e', string.ByteAt(7));
}
void CountChars_WithEllipsis_ReturnsCorrectCount()
{
BString string("Something" B_UTF8_ELLIPSIS);
CPPUNIT_ASSERT_EQUAL(10, string.CountChars());
CPPUNIT_ASSERT_EQUAL(strlen(string.String()), (unsigned)string.Length());
}
void CountChars_Ascii_ReturnsCorrectCount()
{
BString string2("ABCD");
CPPUNIT_ASSERT_EQUAL(4, string2.CountChars());
CPPUNIT_ASSERT_EQUAL(strlen(string2.String()), (unsigned)string2.Length());
}
void CountChars_Combination_ReturnsCorrectCount()
{
static char s[64];
strcpy(s, B_UTF8_ELLIPSIS);
strcat(s, B_UTF8_SMILING_FACE);
BString string3(s);
CPPUNIT_ASSERT_EQUAL(2, string3.CountChars());
CPPUNIT_ASSERT_EQUAL(strlen(string3.String()), (unsigned)string3.Length());
}
void Access_EmptyString_ReturnsZeros()
{
BString empty;
CPPUNIT_ASSERT_EQUAL(0, strcmp(empty.String(), ""));
CPPUNIT_ASSERT_EQUAL(0, empty.Length());
CPPUNIT_ASSERT_EQUAL(0, empty.CountChars());
}
void CountChars_InvalidUtf8_ReturnsCorrectCount()
{
BString invalid("some text with utf8 characters" B_UTF8_ELLIPSIS);
invalid.Truncate(invalid.Length() - 1);
CPPUNIT_ASSERT_EQUAL(31, invalid.CountChars());
}
void LockBuffer_WithCapacity_ReturnsValidPointer()
{
BString locked("a string");
char* ptrstr = locked.LockBuffer(20);
CPPUNIT_ASSERT_EQUAL(0, strcmp(ptrstr, "a string"));
strcat(ptrstr, " to be locked");
locked.UnlockBuffer();
CPPUNIT_ASSERT_EQUAL(0, strcmp(ptrstr, "a string to be locked"));
}
void UnlockBuffer_WithLength_TruncatesString()
{
BString locked2("some text");
char* ptr = locked2.LockBuffer(3);
CPPUNIT_ASSERT_EQUAL(0, strcmp(ptr, "some text"));
locked2.UnlockBuffer(4);
CPPUNIT_ASSERT_EQUAL(0, strcmp(locked2.String(), "some"));
CPPUNIT_ASSERT_EQUAL(4, locked2.Length());
}
void LockBuffer_EmptyString_ReturnsValidPointer()
{
BString emptylocked;
char* ptr = emptylocked.LockBuffer(10);
CPPUNIT_ASSERT_EQUAL(0, strcmp(ptr, ""));
strcat(ptr, "pippo");
emptylocked.UnlockBuffer();
CPPUNIT_ASSERT_EQUAL(0, strcmp(emptylocked.String(), "pippo"));
}
#ifndef TEST_R5
void LockBuffer_ZeroLength_DoesNotCrash()
{
BString crashesR5;
crashesR5.LockBuffer(0);
crashesR5.UnlockBuffer(-1);
CPPUNIT_ASSERT_EQUAL(0, strcmp(crashesR5.String(), ""));
}
#endif
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringAccessTest, getTestSuiteName());
+162
View File
@@ -0,0 +1,162 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringAppendTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringAppendTest);
CPPUNIT_TEST(PlusEquals_BString_AppendsString);
CPPUNIT_TEST(PlusEquals_CString_AppendsString);
CPPUNIT_TEST(PlusEquals_CStringToEmpty_AppendsString);
CPPUNIT_TEST(PlusEquals_NullPointer_IgnoresAppend);
CPPUNIT_TEST(PlusEquals_Char_AppendsChar);
CPPUNIT_TEST(Append_BString_AppendsString);
CPPUNIT_TEST(Append_CString_AppendsString);
CPPUNIT_TEST(Append_CStringToEmpty_AppendsString);
CPPUNIT_TEST(Append_NullPointer_IgnoresAppend);
CPPUNIT_TEST(Append_BStringAndLength_AppendsSubstring);
CPPUNIT_TEST(Append_CStringAndLength_AppendsString);
CPPUNIT_TEST(Append_NullPointerAndLength_IgnoresAppend);
CPPUNIT_TEST(Append_CharAndLength_AppendsMultipleChars);
#ifndef TEST_R5
//CPPUNIT_TEST(Append_CharAndExcessLength_AppendsMultipleChars);
CPPUNIT_TEST(Append_CStringAndExcessLength_AppendsString);
#endif
CPPUNIT_TEST_SUITE_END();
public:
void PlusEquals_BString_AppendsString()
{
BString str1("BASE");
BString str2("APPENDED");
str1 += str2;
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "BASEAPPENDED"));
}
void PlusEquals_CString_AppendsString()
{
BString str1("Base");
str1 += "APPENDED";
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "BaseAPPENDED"));
}
void PlusEquals_CStringToEmpty_AppendsString()
{
BString str1;
str1 += "APPENDEDTONOTHING";
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "APPENDEDTONOTHING"));
}
void PlusEquals_NullPointer_IgnoresAppend()
{
char* tmp = NULL;
BString str1("Base");
str1 += tmp;
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "Base"));
}
void PlusEquals_Char_AppendsChar()
{
BString str1("Base");
str1 += 'C';
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "BaseC"));
}
void Append_BString_AppendsString()
{
BString str1("BASE");
BString str2("APPENDED");
str1.Append(str2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "BASEAPPENDED"));
}
void Append_CString_AppendsString()
{
BString str1("Base");
str1.Append("APPENDED");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "BaseAPPENDED"));
}
void Append_CStringToEmpty_AppendsString()
{
BString str1;
str1.Append("APPENDEDTONOTHING");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "APPENDEDTONOTHING"));
}
void Append_NullPointer_IgnoresAppend()
{
char* tmp = NULL;
BString str1("Base");
str1.Append(tmp);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "Base"));
}
void Append_BStringAndLength_AppendsSubstring()
{
BString str1("BASE");
BString str2("APPENDED");
str1.Append(str2, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "BASEAP"));
}
void Append_CStringAndLength_AppendsString()
{
BString str1("Base");
str1.Append("APPENDED", 40);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "BaseAPPENDED"));
CPPUNIT_ASSERT_EQUAL(strlen("BaseAPPENDED"), (unsigned)str1.Length());
}
void Append_NullPointerAndLength_IgnoresAppend()
{
char* tmp = NULL;
BString str1("BLABLA");
str1.Append(tmp, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "BLABLA"));
}
void Append_CharAndLength_AppendsMultipleChars()
{
BString str1("Base");
str1.Append('C', 5);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "BaseCCCCC"));
}
#ifndef TEST_R5
// TODO: The following test cases only work with hoard2, which will not
// allow allocations via malloc() larger than the largest size-class
// (see threadHeap::malloc(size_t). Other malloc implementations like
// rpmalloc will allow arbitrarily large allocations via create_area().
//
// This test should be made more robust by breaking the dependency on
// the allocator to simulate failures in another way. This may require
// a tricky build configuration to avoid breaking the ABI of BString.
void Append_CharAndExcessLength_AppendsMultipleChars()
{
const int32 OUT_OF_MEM_VAL = 2 * 1000 * 1000 * 1000;
BString str1("Base");
str1.Append('C', OUT_OF_MEM_VAL);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "Base"));
}
void Append_CStringAndExcessLength_AppendsString()
{
const int32 OUT_OF_MEM_VAL = 2 * 1000 * 1000 * 1000;
BString str1("Base");
str1.Append("some more text", OUT_OF_MEM_VAL);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "Basesome more text"));
}
#endif
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringAppendTest, getTestSuiteName());
+163
View File
@@ -0,0 +1,163 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringAssignTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringAssignTest);
CPPUNIT_TEST(Assign_BString_CreatesMatchingString);
CPPUNIT_TEST(Assign_CString_CreatesMatchingString);
#if __cplusplus >= 201103L
CPPUNIT_TEST(Assign_MovableBString_MovesString);
#endif
CPPUNIT_TEST(Assign_NullPointer_CreatesEmptyString);
CPPUNIT_TEST(SetTo_NullPointer_CreatesEmptyString);
CPPUNIT_TEST(SetTo_CString_CreatesMatchingString);
CPPUNIT_TEST(SetTo_BString_CreatesMatchingString);
CPPUNIT_TEST(SetTo_CharAndLength_CreatesRepeatedString);
CPPUNIT_TEST(SetTo_CharAndZeroLength_CreatesEmptyString);
CPPUNIT_TEST(SetTo_CStringAndLength_CreatesSubstring);
CPPUNIT_TEST(Adopt_BString_AdoptsStringAndClearsOriginal);
CPPUNIT_TEST(Adopt_BStringAndLength_AdoptsSubstringAndClearsOriginal);
#ifndef TEST_R5
//CPPUNIT_TEST(SetTo_CharAndExcessLength_CreatesMatchingString);
CPPUNIT_TEST(SetTo_CStringAndExcessLength_CreatesMatchingString);
#endif
CPPUNIT_TEST_SUITE_END();
public:
void Assign_BString_CreatesMatchingString()
{
BString string;
BString string2("Something");
string = string2;
CPPUNIT_ASSERT_EQUAL(string2, string);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "Something"));
}
void Assign_CString_CreatesMatchingString()
{
BString str;
str = "Something Else";
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "Something Else"));
}
#if __cplusplus >= 201103L
void Assign_MovableBString_MovesString()
{
BString movableString("Something movable");
BString str;
str = std::move(movableString);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "Something movable"));
CPPUNIT_ASSERT_EQUAL(0, strcmp(movableString.String(), ""));
}
#endif
void Assign_NullPointer_CreatesEmptyString()
{
char* s = NULL;
BString str;
str = s;
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), ""));
}
void SetTo_NullPointer_CreatesEmptyString()
{
char* s = NULL;
BString str;
str.SetTo(s);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), ""));
}
void SetTo_CString_CreatesMatchingString()
{
BString str;
str.SetTo("BLA");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "BLA"));
}
void SetTo_BString_CreatesMatchingString()
{
BString string("Something");
BString str;
str.SetTo(string);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), string.String()));
}
void SetTo_CharAndLength_CreatesRepeatedString()
{
BString str;
str.SetTo('C', 10);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "CCCCCCCCCC"));
}
void SetTo_CharAndZeroLength_CreatesEmptyString()
{
BString str("ASDSGAFA");
str.SetTo('C', 0);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), ""));
}
void SetTo_CStringAndLength_CreatesSubstring()
{
BString str;
str.SetTo("ABC", 10);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "ABC"));
}
void Adopt_BString_AdoptsStringAndClearsOriginal()
{
BString string2("Something");
BString str;
str.Adopt(string2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "Something"));
CPPUNIT_ASSERT_EQUAL(0, strcmp(string2.String(), ""));
}
void Adopt_BStringAndLength_AdoptsSubstringAndClearsOriginal()
{
BString newstring("SomethingElseAgain");
BString str;
str.Adopt(newstring, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "So"));
CPPUNIT_ASSERT_EQUAL(2, str.Length());
CPPUNIT_ASSERT_EQUAL(0, strcmp(newstring.String(), ""));
}
#ifndef TEST_R5
// TODO: The following test cases only work with hoard2, which will not
// allow allocations via malloc() larger than the largest size-class
// (see threadHeap::malloc(size_t). Other malloc implementations like
// rpmalloc will allow arbitrarily large allocations via create_area().
//
// This test should be made more robust by breaking the dependency on
// the allocator to simulate failures in another way. This may require
// a tricky build configuration to avoid breaking the ABI of BString.
void SetTo_CharAndExcessLength_CreatesMatchingString()
{
const int32 OUT_OF_MEM_VAL = 2 * 1000 * 1000 * 1000;
BString str("dummy");
str.SetTo('C', OUT_OF_MEM_VAL);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "dummy"));
}
void SetTo_CStringAndExcessLength_CreatesMatchingString()
{
const int32 OUT_OF_MEM_VAL = 2 * 1000 * 1000 * 1000;
BString str("dummy");
str.SetTo("some more text", OUT_OF_MEM_VAL);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "some more text"));
}
#endif
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringAssignTest, getTestSuiteName());
+93
View File
@@ -0,0 +1,93 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringCaseTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringCaseTest);
CPPUNIT_TEST(Capitalize_NormalString_CapitalizesFirstLetter);
CPPUNIT_TEST(Capitalize_StringStartingWithNumber_RemainsUnchanged);
CPPUNIT_TEST(Capitalize_EmptyString_RemainsEmpty);
CPPUNIT_TEST(ToLower_MixedCase_ConvertsToLowercase);
CPPUNIT_TEST(ToLower_EmptyString_RemainsEmpty);
CPPUNIT_TEST(ToUpper_MixedCase_ConvertsToUppercase);
CPPUNIT_TEST(ToUpper_EmptyString_RemainsEmpty);
CPPUNIT_TEST(CapitalizeEachWord_MixedString_CapitalizesWords);
CPPUNIT_TEST(CapitalizeEachWord_EmptyString_RemainsEmpty);
CPPUNIT_TEST_SUITE_END();
public:
void Capitalize_NormalString_CapitalizesFirstLetter()
{
BString string("this is a sentence");
string.Capitalize();
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "This is a sentence"));
}
void Capitalize_StringStartingWithNumber_RemainsUnchanged()
{
BString string("134this is a sentence");
string.Capitalize();
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "134this is a sentence"));
}
void Capitalize_EmptyString_RemainsEmpty()
{
BString string;
string.Capitalize();
CPPUNIT_ASSERT_EQUAL(BString(""), string);
}
void ToLower_MixedCase_ConvertsToLowercase()
{
BString string("1a2B3c4d5e6f7G");
string.ToLower();
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "1a2b3c4d5e6f7g"));
}
void ToLower_EmptyString_RemainsEmpty()
{
BString string;
string.ToLower();
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), ""));
}
void ToUpper_MixedCase_ConvertsToUppercase()
{
BString string("1a2b3c4d5E6f7g");
string.ToUpper();
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "1A2B3C4D5E6F7G"));
}
void ToUpper_EmptyString_RemainsEmpty()
{
BString string;
string.ToUpper();
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), ""));
}
void CapitalizeEachWord_MixedString_CapitalizesWords()
{
BString string("each wOrd 3will_be >capiTalized");
string.CapitalizeEachWord();
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "Each Word 3Will_Be >Capitalized"));
}
void CapitalizeEachWord_EmptyString_RemainsEmpty()
{
BString string;
string.CapitalizeEachWord();
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), ""));
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringCaseTest, getTestSuiteName());
@@ -0,0 +1,159 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringCompareTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringCompareTest);
CPPUNIT_TEST(LessThan_BString_ReturnsTrueForSmaller);
CPPUNIT_TEST(LessThanOrEqual_BString_ReturnsTrueForSmaller);
CPPUNIT_TEST(LessThanOrEqual_BString_ReturnsTrueForEqual);
CPPUNIT_TEST(Equals_BString_ReturnsTrueForEqual);
CPPUNIT_TEST(Equals_BString_ReturnsFalseForUnequal);
CPPUNIT_TEST(GreaterThanOrEqual_BString_ReturnsTrueForGreater);
CPPUNIT_TEST(GreaterThanOrEqual_BString_ReturnsTrueForEqual);
CPPUNIT_TEST(GreaterThan_BString_ReturnsTrueForGreater);
CPPUNIT_TEST(NotEquals_BString_ReturnsFalseForEqual);
CPPUNIT_TEST(NotEquals_BString_ReturnsTrueForUnequal);
CPPUNIT_TEST(LessThan_CString_ReturnsTrueForSmaller);
CPPUNIT_TEST(LessThanOrEqual_CString_ReturnsTrueForSmallerOrEqual);
CPPUNIT_TEST(Equals_CString_ReturnsTrueForEqual);
CPPUNIT_TEST(Equals_CString_ReturnsFalseForUnequal);
CPPUNIT_TEST(GreaterThanOrEqual_CString_ReturnsTrueForGreaterOrEqual);
CPPUNIT_TEST(GreaterThan_CString_ReturnsTrueForGreater);
CPPUNIT_TEST(NotEquals_CString_ReturnsFalseForEqual);
CPPUNIT_TEST(NotEquals_CString_ReturnsTrueForUnequal);
CPPUNIT_TEST_SUITE_END();
public:
void LessThan_BString_ReturnsTrueForSmaller()
{
BString string1("11111_a");
BString string2("22222_b");
CPPUNIT_ASSERT(string1 < string2);
}
void LessThanOrEqual_BString_ReturnsTrueForSmaller()
{
BString string1("11111_a");
BString string2("22222_b");
CPPUNIT_ASSERT(string1 <= string2);
}
void LessThanOrEqual_BString_ReturnsTrueForEqual()
{
BString string1("11111");
BString string2("11111");
CPPUNIT_ASSERT(string1 <= string2);
}
void Equals_BString_ReturnsTrueForEqual()
{
BString string1("string");
BString string2("string");
CPPUNIT_ASSERT(string1 == string2);
}
void Equals_BString_ReturnsFalseForUnequal()
{
BString string1("text");
BString string2("string");
CPPUNIT_ASSERT((string1 == string2) == false);
}
void GreaterThanOrEqual_BString_ReturnsTrueForGreater()
{
BString string1("BBBBB");
BString string2("AAAAA");
CPPUNIT_ASSERT(string1 >= string2);
}
void GreaterThanOrEqual_BString_ReturnsTrueForEqual()
{
BString string1("11111");
BString string2("11111");
CPPUNIT_ASSERT(string1 >= string2);
}
void GreaterThan_BString_ReturnsTrueForGreater()
{
BString string1("BBBBB");
BString string2("AAAAA");
CPPUNIT_ASSERT(string1 > string2);
}
void NotEquals_BString_ReturnsFalseForEqual()
{
BString string1("string");
BString string2("string");
CPPUNIT_ASSERT((string1 != string2) == false);
}
void NotEquals_BString_ReturnsTrueForUnequal()
{
BString string1("text");
BString string2("string");
CPPUNIT_ASSERT(string1 != string2);
}
void LessThan_CString_ReturnsTrueForSmaller()
{
BString string1("AAAAA");
CPPUNIT_ASSERT(string1 < "BBBBB");
}
void LessThanOrEqual_CString_ReturnsTrueForSmallerOrEqual()
{
BString string1("AAAAA");
CPPUNIT_ASSERT(string1 <= "BBBBB");
CPPUNIT_ASSERT(string1 <= "AAAAA");
}
void Equals_CString_ReturnsTrueForEqual()
{
BString string1("AAAAA");
CPPUNIT_ASSERT(string1 == "AAAAA");
}
void Equals_CString_ReturnsFalseForUnequal()
{
BString string1("AAAAA");
CPPUNIT_ASSERT((string1 == "BBBB") == false);
}
void GreaterThanOrEqual_CString_ReturnsTrueForGreaterOrEqual()
{
BString string1("BBBBB");
CPPUNIT_ASSERT(string1 >= "AAAAA");
CPPUNIT_ASSERT(string1 >= "BBBBB");
}
void GreaterThan_CString_ReturnsTrueForGreater()
{
BString string1("BBBBB");
CPPUNIT_ASSERT(string1 > "AAAAA");
}
void NotEquals_CString_ReturnsFalseForEqual()
{
BString string1("AAAAA");
CPPUNIT_ASSERT((string1 != "AAAAA") == false);
}
void NotEquals_CString_ReturnsTrueForUnequal()
{
BString string1("AAAAA");
CPPUNIT_ASSERT(string1 != "BBBB");
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringCompareTest, getTestSuiteName());
@@ -0,0 +1,90 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringConstructionTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringConstructionTest);
CPPUNIT_TEST(Construct_Empty_CreatesEmptyString);
CPPUNIT_TEST(Construct_FromCString_CreatesMatchingString);
CPPUNIT_TEST(Construct_FromNull_CreatesEmptyString);
CPPUNIT_TEST(Construct_FromBString_CreatesMatchingString);
CPPUNIT_TEST(Construct_FromCStringWithLength_CreatesSubstring);
#if __cplusplus >= 201103L
CPPUNIT_TEST(Construct_FromMovableBString_MovesString);
#endif
CPPUNIT_TEST(Construct_FromCStringWithExcessLength_CreatesMatchingString);
CPPUNIT_TEST_SUITE_END();
public:
void Construct_Empty_CreatesEmptyString()
{
BString string;
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), ""));
CPPUNIT_ASSERT_EQUAL(0, string.Length());
}
void Construct_FromCString_CreatesMatchingString()
{
const char* str = "Something";
BString string(str);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), str));
CPPUNIT_ASSERT_EQUAL((unsigned)strlen(str), string.Length());
}
void Construct_FromNull_CreatesEmptyString()
{
BString string(NULL);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), ""));
CPPUNIT_ASSERT_EQUAL(0, string.Length());
}
void Construct_FromBString_CreatesMatchingString()
{
BString anotherString("Something Else");
BString string(anotherString);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), anotherString.String()));
CPPUNIT_ASSERT_EQUAL(anotherString.Length(), string.Length());
}
void Construct_FromCStringWithLength_CreatesSubstring()
{
const char* str = "Something";
BString string(str, 5);
CPPUNIT_ASSERT(strcmp(string.String(), str) != 0);
CPPUNIT_ASSERT_EQUAL(0, strncmp(string.String(), str, 5));
CPPUNIT_ASSERT_EQUAL(5, string.Length());
}
#if __cplusplus >= 201103L
void Construct_FromMovableBString_MovesString()
{
const char* str = "Something";
BString movableString(str);
BString string(std::move(movableString));
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), str));
CPPUNIT_ASSERT_EQUAL((unsigned)strlen(str), string.Length());
CPPUNIT_ASSERT_EQUAL(0, strcmp(movableString.String(), ""));
CPPUNIT_ASSERT_EQUAL(0, movableString.Length());
}
#endif
void Construct_FromCStringWithExcessLength_CreatesMatchingString()
{
const char* str = "Something";
BString string(str, 255);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), str));
CPPUNIT_ASSERT_EQUAL((unsigned)strlen(str), string.Length());
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringConstructionTest, getTestSuiteName());
+129
View File
@@ -0,0 +1,129 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringEscapeTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringEscapeTest);
CPPUNIT_TEST(CharacterEscape_ValidString_EscapesChars);
CPPUNIT_TEST(CharacterEscape_EmptyString_RemainsEmpty);
CPPUNIT_TEST(CharacterEscape_StringWithoutChars_RemainsUnchanged);
CPPUNIT_TEST(CharacterEscape_WithOriginalString_EscapesAndAssigns);
CPPUNIT_TEST(CharacterEscape_EmptyStringWithOriginalString_EscapesAndAssigns);
CPPUNIT_TEST(CharacterDeescape_ValidString_DeescapesChars);
CPPUNIT_TEST(CharacterDeescape_EmptyString_RemainsEmpty);
CPPUNIT_TEST(CharacterDeescape_StringWithoutEscapeChar_RemainsUnchanged);
CPPUNIT_TEST(CharacterDeescape_WithOriginalString_DeescapesAndAssigns);
CPPUNIT_TEST(CharacterDeescape_EmptyStringWithOriginalString_DeescapesAndAssigns);
CPPUNIT_TEST(CharacterDeescape_OriginalStringWithoutEscapeChar_AssignsUnchanged);
#ifndef TEST_R5
CPPUNIT_TEST(CharacterEscape_WithNullOriginalString_AssignsEmpty);
CPPUNIT_TEST(CharacterDeescape_WithNullOriginalString_AssignsEmpty);
#endif
CPPUNIT_TEST_SUITE_END();
public:
void CharacterEscape_ValidString_EscapesChars()
{
BString string1("abcdefghi");
string1.CharacterEscape("acf", '/');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "/ab/cde/fghi"));
}
void CharacterEscape_EmptyString_RemainsEmpty()
{
BString string1;
string1.CharacterEscape("abc", '/');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), ""));
}
void CharacterEscape_StringWithoutChars_RemainsUnchanged()
{
BString string1("abcdefghi");
string1.CharacterEscape("z34", 'z');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "abcdefghi"));
}
void CharacterEscape_WithOriginalString_EscapesAndAssigns()
{
BString string1("something");
string1.CharacterEscape("newstring", "esi", '0');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "n0ew0str0ing"));
}
void CharacterEscape_EmptyStringWithOriginalString_EscapesAndAssigns()
{
BString string1;
string1.CharacterEscape("newstring", "esi", '0');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "n0ew0str0ing"));
}
void CharacterDeescape_ValidString_DeescapesChars()
{
BString string1("/a/nh/g/bhhgy/fgtuhjkb/");
string1.CharacterDeescape('/');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "anhgbhhgyfgtuhjkb"));
}
void CharacterDeescape_EmptyString_RemainsEmpty()
{
BString string1;
string1.CharacterDeescape('/');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), ""));
}
void CharacterDeescape_StringWithoutEscapeChar_RemainsUnchanged()
{
BString string1("/a/nh/g/bhhgy/fgtuhjkb/");
string1.CharacterDeescape('-');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "/a/nh/g/bhhgy/fgtuhjkb/"));
}
void CharacterDeescape_WithOriginalString_DeescapesAndAssigns()
{
BString string1("oldString");
string1.CharacterDeescape("-ne-ws-tri-ng-", '-');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "newstring"));
}
void CharacterDeescape_EmptyStringWithOriginalString_DeescapesAndAssigns()
{
BString string1;
string1.CharacterDeescape("new/str/ing", '/');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "newstring"));
}
void CharacterDeescape_OriginalStringWithoutEscapeChar_AssignsUnchanged()
{
BString string1("Old");
string1.CharacterDeescape("/a/nh/g/bhhgy/fgtuhjkb/", '-');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "/a/nh/g/bhhgy/fgtuhjkb/"));
}
#ifndef TEST_R5
void CharacterEscape_WithNullOriginalString_AssignsEmpty()
{
BString string1("something");
string1.CharacterEscape((char*)NULL, "ei", '-');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), ""));
}
void CharacterDeescape_WithNullOriginalString_AssignsEmpty()
{
BString string1("pippo");
string1.CharacterDeescape((char*)NULL, '/');
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), ""));
}
#endif
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringEscapeTest, getTestSuiteName());
@@ -0,0 +1,134 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringFormatAppendTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringFormatAppendTest);
CPPUNIT_TEST(Append_CString_AppendsString);
CPPUNIT_TEST(Append_BString_AppendsString);
CPPUNIT_TEST(Append_Char_AppendsChars);
CPPUNIT_TEST(Append_Int_AppendsInt);
CPPUNIT_TEST(Append_NegativeInt_AppendsInt);
CPPUNIT_TEST(Append_UnsignedInt_AppendsUnsignedInt);
CPPUNIT_TEST(Append_Uint32_AppendsUint32);
CPPUNIT_TEST(Append_Int32_AppendsInt32);
CPPUNIT_TEST(Append_NegativeInt32_AppendsInt32);
CPPUNIT_TEST(Append_Uint64_AppendsUint64);
CPPUNIT_TEST(Append_Int64_AppendsInt64);
CPPUNIT_TEST(Append_NegativeInt64_AppendsInt64);
CPPUNIT_TEST(Append_Float_AppendsFloat);
CPPUNIT_TEST(Append_MultipleTypes_AppendsAll);
CPPUNIT_TEST_SUITE_END();
public:
void Append_CString_AppendsString()
{
BString string("some");
string << " " << "text";
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "some text"));
}
void Append_BString_AppendsString()
{
BString string("some ");
BString string2("text");
string << string2;
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "some text"));
}
void Append_Char_AppendsChars()
{
BString string("str");
string << 'i' << 'n' << 'g';
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "string"));
}
void Append_Int_AppendsInt()
{
BString string("level ");
string << (int)42;
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "level 42"));
}
void Append_NegativeInt_AppendsInt()
{
BString string("error ");
string << (int)-1;
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "error -1"));
}
void Append_UnsignedInt_AppendsUnsignedInt()
{
BString string("number ");
string << (unsigned int)296;
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "number 296"));
}
void Append_Uint32_AppendsUint32()
{
BString string;
string << (uint32)102456;
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "102456"));
}
void Append_Int32_AppendsInt32()
{
BString string;
string << (int32)112456;
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "112456"));
}
void Append_NegativeInt32_AppendsInt32()
{
BString string;
string << (int32)-112475;
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "-112475"));
}
void Append_Uint64_AppendsUint64()
{
BString string;
string << (uint64)1145267987;
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "1145267987"));
}
void Append_Int64_AppendsInt64()
{
BString string;
string << (int64)112456;
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "112456"));
}
void Append_NegativeInt64_AppendsInt64()
{
BString string;
string << (int64)-112475;
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "-112475"));
}
void Append_Float_AppendsFloat()
{
BString string;
string << (float)34.542;
CPPUNIT_ASSERT_EQUAL(0, strcmp(string.String(), "34.54"));
}
void Append_MultipleTypes_AppendsAll()
{
BString s;
s << "This" << ' ' << "is" << ' ' << 'a' << ' ' << "test" << ' ' << "sentence";
CPPUNIT_ASSERT_EQUAL(0, strcmp(s.String(), "This is a test sentence"));
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringFormatAppendTest, getTestSuiteName());
+149
View File
@@ -0,0 +1,149 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringInsertTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringInsertTest);
CPPUNIT_TEST(CStringPos_InsertsString);
CPPUNIT_TEST(CStringNegativePos_InsertsStringWithOffset);
CPPUNIT_TEST(CStringLenPos_InsertsSubstring);
#ifndef TEST_R5
CPPUNIT_TEST(CStringInvalidPos_IgnoresInsertion);
CPPUNIT_TEST(CStringLargeNegativePos_ClearsString);
CPPUNIT_TEST(CStringLenInvalidPos_IgnoresInsertion);
#endif
CPPUNIT_TEST(CStringLargeLenPos_InsertsWholeString);
CPPUNIT_TEST(CStringOffsetLenPos_InsertsSubstringFromOffset);
CPPUNIT_TEST(CharCountPos_InsertsMultipleChars);
CPPUNIT_TEST(CharCountNegativePos_InsertsMultipleCharsAtZero);
CPPUNIT_TEST(BStringPos_InsertsString);
CPPUNIT_TEST(SelfPos_IgnoresInsertion);
CPPUNIT_TEST(BStringNegativePos_InsertsStringWithOffset);
CPPUNIT_TEST(BStringLenPos_InsertsSubstring);
CPPUNIT_TEST(BStringOffsetLenPos_InsertsSubstringFromOffset);
CPPUNIT_TEST_SUITE_END();
public:
void CStringPos_InsertsString()
{
BString str1("String");
str1.Insert("INSERTED", 3);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "StrINSERTEDing"));
}
void CStringNegativePos_InsertsStringWithOffset()
{
BString str1;
str1.Insert("INSERTED", -1);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "NSERTED"));
}
void CStringLenPos_InsertsSubstring()
{
BString str1("string");
str1.Insert("INSERTED", 2, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "stINring"));
}
#ifndef TEST_R5
void CStringInvalidPos_IgnoresInsertion()
{
BString str1("String");
str1.Insert("INSERTED", 10);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "String"));
}
void CStringLargeNegativePos_ClearsString()
{
BString str1;
str1.Insert("INSERTED", -142364253);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), ""));
}
void CStringLenInvalidPos_IgnoresInsertion()
{
BString str1("string");
str1.Insert("INSERTED", 2, 30);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "string"));
}
#endif
void CStringLargeLenPos_InsertsWholeString()
{
BString str1("string");
str1.Insert("INSERTED", 10, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "stINSERTEDring"));
}
void CStringOffsetLenPos_InsertsSubstringFromOffset()
{
BString str1("string");
str1.Insert("INSERTED", 4, 30, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "stRTEDring"));
}
void CharCountPos_InsertsMultipleChars()
{
BString str1("string");
str1.Insert('P', 5, 3);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "strPPPPPing"));
}
void CharCountNegativePos_InsertsMultipleCharsAtZero()
{
BString str1("string");
str1.Insert('P', 5, -2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "PPPstring"));
}
void BStringPos_InsertsString()
{
BString str1("string");
BString str2("INSERTED");
str1.Insert(str2, 0);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "INSERTEDstring"));
}
void SelfPos_IgnoresInsertion()
{
BString str1("string");
str1.Insert(str1, 0);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "string"));
}
void BStringNegativePos_InsertsStringWithOffset()
{
BString str1;
BString str2("INSERTED");
str1.Insert(str2, -1);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "NSERTED"));
}
void BStringLenPos_InsertsSubstring()
{
BString str1("string");
BString str2("INSERTED");
str1.Insert(str2, 2, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "stINring"));
}
void BStringOffsetLenPos_InsertsSubstringFromOffset()
{
BString str1("string");
BString str2("INSERTED");
str1.Insert(str2, 4, 30, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "stRTEDring"));
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringInsertTest, getTestSuiteName());
@@ -0,0 +1,80 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <UTF8.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringPrependTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringPrependTest);
CPPUNIT_TEST(BString_PrependsString);
CPPUNIT_TEST(CString_PrependsString);
CPPUNIT_TEST(NullPointer_IgnoresPrepend);
CPPUNIT_TEST(CStringAndLength_PrependsSubstring);
CPPUNIT_TEST(BStringAndLength_PrependsSubstring);
CPPUNIT_TEST(CharAndLength_PrependsMultipleChars);
CPPUNIT_TEST(CStringToEmpty_PrependsString);
CPPUNIT_TEST_SUITE_END();
public:
void BString_PrependsString()
{
BString str1("a String");
BString str2("PREPENDED");
str1.Prepend(str2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "PREPENDEDa String"));
}
void CString_PrependsString()
{
BString str1("String");
str1.Prepend("PREPEND");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "PREPENDString"));
}
void NullPointer_IgnoresPrepend()
{
BString str1("String");
str1.Prepend((char*)NULL);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "String"));
}
void CStringAndLength_PrependsSubstring()
{
BString str1("String");
str1.Prepend("PREPENDED", 3);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "PREString"));
}
void BStringAndLength_PrependsSubstring()
{
BString str1("String");
BString str2("PREPEND", 4);
str1.Prepend(str2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "PREPString"));
}
void CharAndLength_PrependsMultipleChars()
{
BString str1("aString");
str1.Prepend('c', 4);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "ccccaString"));
}
void CStringToEmpty_PrependsString()
{
BString str1;
str1.Prepend("PREPENDED");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str1.String(), "PREPENDED"));
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringPrependTest, getTestSuiteName());
+278
View File
@@ -0,0 +1,278 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringRemoveTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringRemoveTest);
CPPUNIT_TEST(Truncate_Lazy);
CPPUNIT_TEST(Truncate_NotLazy);
#ifndef TEST_R5
CPPUNIT_TEST(Truncate_NegativeLength);
#endif
CPPUNIT_TEST(Truncate_LongerLength);
CPPUNIT_TEST(Truncate_EmptyString);
CPPUNIT_TEST(Remove_ValidRange);
CPPUNIT_TEST(Remove_EmptyString);
CPPUNIT_TEST(Remove_BeyondEnd);
CPPUNIT_TEST(Remove_ExceedsLength);
CPPUNIT_TEST(Remove_NegativeIndex);
CPPUNIT_TEST(RemoveFirst_BString_Match);
CPPUNIT_TEST(RemoveFirst_BString_NoMatch);
CPPUNIT_TEST(RemoveLast_BString_Match);
CPPUNIT_TEST(RemoveLast_BString_NoMatch);
CPPUNIT_TEST(RemoveAll_BString_Match);
CPPUNIT_TEST(RemoveAll_BString_NoMatch);
CPPUNIT_TEST(RemoveFirst_CString_Match);
CPPUNIT_TEST(RemoveFirst_CString_NoMatch);
CPPUNIT_TEST(RemoveFirst_CString_Null);
CPPUNIT_TEST(RemoveLast_CString_Match);
CPPUNIT_TEST(RemoveLast_CString_NoMatch);
CPPUNIT_TEST(RemoveAll_CString_Match);
CPPUNIT_TEST(RemoveAll_CString_NoMatch);
CPPUNIT_TEST(RemoveSet_Match);
CPPUNIT_TEST(RemoveSet_NoMatch);
CPPUNIT_TEST(MoveInto_BString_ValidRange);
CPPUNIT_TEST(MoveInto_BString_ExceedsLength);
CPPUNIT_TEST(MoveInto_CString_ValidRange);
CPPUNIT_TEST(MoveInto_CString_ExceedsLength);
CPPUNIT_TEST_SUITE_END();
public:
void Truncate_Lazy()
{
BString string1("This is a long string");
string1.Truncate(14, true);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "This is a long"));
CPPUNIT_ASSERT_EQUAL(14, string1.Length());
}
void Truncate_NotLazy()
{
BString string1("This is a long string");
string1.Truncate(14, false);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "This is a long"));
CPPUNIT_ASSERT_EQUAL(14, string1.Length());
}
#ifndef TEST_R5
void Truncate_NegativeLength()
{
// it crashes r5 implementation, but ours works fine here,
// in this case, we just truncate to 0
BString string1("This is a long string");
string1.Truncate(-3);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), ""));
CPPUNIT_ASSERT_EQUAL(0, string1.Length());
}
#endif
void Truncate_LongerLength()
{
BString string1("This is a long string");
string1.Truncate(45);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "This is a long string"));
CPPUNIT_ASSERT_EQUAL(21, string1.Length());
}
void Truncate_EmptyString()
{
BString string1;
string1.Truncate(0);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), ""));
CPPUNIT_ASSERT_EQUAL(0, string1.Length());
}
void Remove_ValidRange()
{
BString string1("a String");
string1.Remove(2, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "a ring"));
}
void Remove_EmptyString()
{
BString string1;
string1.Remove(2, 1);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), ""));
}
void Remove_BeyondEnd()
{
BString string1("a String");
string1.Remove(20, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "a String"));
}
void Remove_ExceedsLength()
{
BString string1("a String");
string1.Remove(4, 30);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "a St"));
}
void Remove_NegativeIndex()
{
BString string1("a String");
string1.Remove(-3, 5);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "ing"));
}
void RemoveFirst_BString_Match()
{
BString string1("first second first");
BString string2("first");
string1.RemoveFirst(string2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), " second first"));
}
void RemoveFirst_BString_NoMatch()
{
BString string1("first second first");
BString string2("noway");
string1.RemoveFirst(string2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "first second first"));
}
void RemoveLast_BString_Match()
{
BString string1("first second first");
BString string2("first");
string1.RemoveLast(string2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "first second "));
}
void RemoveLast_BString_NoMatch()
{
BString string1("first second first");
BString string2("noway");
string1.RemoveLast(string2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "first second first"));
}
void RemoveAll_BString_Match()
{
BString string1("first second first");
BString string2("first");
string1.RemoveAll(string2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), " second "));
}
void RemoveAll_BString_NoMatch()
{
BString string1("first second first");
BString string2("noway");
string1.RemoveAll(string2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "first second first"));
}
void RemoveFirst_CString_Match()
{
BString string1("first second first");
string1.RemoveFirst("first");
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), " second first"));
}
void RemoveFirst_CString_NoMatch()
{
BString string1("first second first");
string1.RemoveFirst("noway");
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "first second first"));
}
void RemoveFirst_CString_Null()
{
BString string1("first second first");
string1.RemoveFirst((char*)NULL);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "first second first"));
}
void RemoveLast_CString_Match()
{
BString string1("first second first");
string1.RemoveLast("first");
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "first second "));
}
void RemoveLast_CString_NoMatch()
{
BString string1("first second first");
string1.RemoveLast("noway");
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "first second first"));
}
void RemoveAll_CString_Match()
{
BString string1("first second first");
string1.RemoveAll("first");
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), " second "));
}
void RemoveAll_CString_NoMatch()
{
BString string1("first second first");
string1.RemoveAll("noway");
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "first second first"));
}
void RemoveSet_Match()
{
BString string1("a sentence with (3) (642) numbers (2) in it");
string1.RemoveSet("()3624 ");
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "asentencewithnumbersinit"));
}
void RemoveSet_NoMatch()
{
BString string1("a string");
string1.RemoveSet("1345");
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "a string"));
}
void MoveInto_BString_ValidRange()
{
BString string1("some text");
BString string2("string");
string2.MoveInto(string1, 3, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "in"));
CPPUNIT_ASSERT_EQUAL(0, strcmp(string2.String(), "strg"));
}
void MoveInto_BString_ExceedsLength()
{
BString string1("some text");
BString string2("string");
string2.MoveInto(string1, 0, 200);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "string"));
CPPUNIT_ASSERT_EQUAL(0, strcmp(string2.String(), ""));
}
void MoveInto_CString_ValidRange()
{
char dest[100];
memset(dest, 0, 100);
BString string1("some text");
string1.MoveInto(dest, 3, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(dest, "e "));
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "somtext"));
}
void MoveInto_CString_ExceedsLength()
{
char dest[100];
BString string1("some text");
memset(dest, 0, 100);
string1.MoveInto(dest, 0, 50);
CPPUNIT_ASSERT_EQUAL(0, strcmp(dest, "some text"));
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), ""));
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringRemoveTest, getTestSuiteName());
@@ -0,0 +1,485 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringReplaceTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringReplaceTest);
CPPUNIT_TEST(ReplaceFirst_Char_Match);
CPPUNIT_TEST(ReplaceFirst_Char_NoMatch);
CPPUNIT_TEST(ReplaceLast_Char_Match);
CPPUNIT_TEST(ReplaceLast_Char_NoMatch);
CPPUNIT_TEST(ReplaceAll_Char_Match);
CPPUNIT_TEST(ReplaceAll_Char_NoMatch);
CPPUNIT_TEST(ReplaceAll_Char_Same);
CPPUNIT_TEST(ReplaceAll_Char_WithOffset);
CPPUNIT_TEST(Replace_Char_InRange);
CPPUNIT_TEST(Replace_Char_NoMatchInRange);
CPPUNIT_TEST(Replace_Char_EmptyString);
CPPUNIT_TEST(ReplaceFirst_String_Match);
CPPUNIT_TEST(ReplaceFirst_String_NoMatch);
CPPUNIT_TEST(ReplaceFirst_String_Null);
CPPUNIT_TEST(ReplaceLast_String_Match);
CPPUNIT_TEST(ReplaceLast_String_NoMatch);
CPPUNIT_TEST(ReplaceLast_String_Null);
CPPUNIT_TEST(ReplaceAll_String_Match);
CPPUNIT_TEST(ReplaceAll_String_NoMatch);
CPPUNIT_TEST(ReplaceAll_String_Null);
CPPUNIT_TEST(ReplaceAll_String_SubMatch);
CPPUNIT_TEST(IReplaceAll_String_Match);
CPPUNIT_TEST(IReplaceAll_String_Same);
CPPUNIT_TEST(IReplaceFirst_Char_Match);
CPPUNIT_TEST(IReplaceFirst_Char_NoMatch);
CPPUNIT_TEST(IReplaceLast_Char_Match);
CPPUNIT_TEST(IReplaceLast_Char_NoMatch);
CPPUNIT_TEST(IReplaceAll_Char_Match);
CPPUNIT_TEST(IReplaceAll_Char_Same);
CPPUNIT_TEST(IReplaceAll_Char_NoMatch);
CPPUNIT_TEST(IReplaceAll_Char_WithOffset);
CPPUNIT_TEST(IReplace_Char_InRange);
CPPUNIT_TEST(IReplace_Char_NoMatchInRange);
CPPUNIT_TEST(IReplace_Char_EmptyString);
CPPUNIT_TEST(IReplaceFirst_String_MatchIgnoreCase);
CPPUNIT_TEST(IReplaceFirst_String_NoMatch);
CPPUNIT_TEST(IReplaceFirst_String_Null);
#ifndef TEST_R5
CPPUNIT_TEST(IReplaceLast_String_MatchIgnoreCase);
#endif
CPPUNIT_TEST(IReplaceLast_String_NoMatch);
CPPUNIT_TEST(IReplaceLast_String_Null);
CPPUNIT_TEST(IReplaceAll_String_MatchIgnoreCase);
CPPUNIT_TEST(IReplaceAll_String_NoMatch);
CPPUNIT_TEST(IReplaceAll_String_MatchLengthy);
CPPUNIT_TEST(IReplaceAll_String_Null);
CPPUNIT_TEST(ReplaceSet_Char_Single);
CPPUNIT_TEST(ReplaceSet_Char_Multiple);
CPPUNIT_TEST(ReplaceSet_Char_Same);
#ifndef TEST_R5
CPPUNIT_TEST(ReplaceSet_String_Match);
CPPUNIT_TEST(ReplaceSet_String_Swap);
CPPUNIT_TEST(ReplaceSet_String_Erase);
#endif
CPPUNIT_TEST(ReplaceSet_String_Perf1);
CPPUNIT_TEST(ReplaceSet_String_Perf2);
CPPUNIT_TEST(ReplaceAll_String_Perf1);
CPPUNIT_TEST(ReplaceAll_String_Perf2);
CPPUNIT_TEST(ReplaceSet_String_Perf3);
CPPUNIT_TEST_SUITE_END();
public:
void ReplaceFirst_Char_Match()
{
BString str("test string");
str.ReplaceFirst('t', 'b');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "best string"));
}
void ReplaceFirst_Char_NoMatch()
{
BString str("test string");
str.ReplaceFirst('x', 'b');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "test string"));
}
void ReplaceLast_Char_Match()
{
BString str("test string");
str.ReplaceLast('t', 'w');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "test swring"));
}
void ReplaceLast_Char_NoMatch()
{
BString str("test string");
str.ReplaceLast('x', 'b');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "test string"));
}
void ReplaceAll_Char_Match()
{
BString str("test string");
str.ReplaceAll('t', 'i');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "iesi siring"));
}
void ReplaceAll_Char_NoMatch()
{
BString str("test string");
str.ReplaceAll('x', 'b');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "test string"));
}
void ReplaceAll_Char_Same()
{
BString str("test string");
str.ReplaceAll('t', 't');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "test string"));
}
void ReplaceAll_Char_WithOffset()
{
BString str("test string");
str.ReplaceAll('t', 'i', 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "tesi siring"));
}
void Replace_Char_InRange()
{
BString str("she sells sea shells on the sea shore");
str.Replace('s', 't', 4, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she tellt tea thells on the sea shore"));
}
void Replace_Char_NoMatchInRange()
{
BString str("she sells sea shells on the sea shore");
str.Replace('s', 's', 4, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells sea shells on the sea shore"));
}
void Replace_Char_EmptyString()
{
BString str;
str.Replace('s', 'x', 12, 32);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), ""));
}
void ReplaceFirst_String_Match()
{
BString str("she sells sea shells on the seashore");
str.ReplaceFirst("sea", "the");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells the shells on the seashore"));
}
void ReplaceFirst_String_NoMatch()
{
BString str("she sells sea shells on the seashore");
str.ReplaceFirst("tex", "the");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells sea shells on the seashore"));
}
void ReplaceFirst_String_Null()
{
BString str("Error moving \"%name\"");
str.ReplaceFirst("%name", NULL);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "Error moving \"\""));
}
void ReplaceLast_String_Match()
{
BString str("she sells sea shells on the seashore");
str.ReplaceLast("sea", "the");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells sea shells on the theshore"));
}
void ReplaceLast_String_NoMatch()
{
BString str("she sells sea shells on the seashore");
str.ReplaceLast("tex", "the");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells sea shells on the seashore"));
}
void ReplaceLast_String_Null()
{
BString str("she sells sea shells on the seashore");
str.ReplaceLast("sea", NULL);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells sea shells on the shore"));
}
void ReplaceAll_String_Match()
{
BString str("abc abc abc");
str.ReplaceAll("ab", "abc");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "abcc abcc abcc"));
}
void ReplaceAll_String_NoMatch()
{
BString str("abc abc abc");
str.ReplaceAll("abc", "abc");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "abc abc abc"));
}
void ReplaceAll_String_Null()
{
BString str("abc abc abc");
str.ReplaceAll("abc", NULL);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), " "));
}
void ReplaceAll_String_SubMatch()
{
BString str("she sells sea shells on the seashore");
str.ReplaceAll("tex", "the");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells sea shells on the seashore"));
}
void IReplaceAll_String_Match()
{
BString str("she sells sea shells on the seashore");
str.IReplaceAll("sea", "the", 11);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells sea shells on the theshore"));
}
void IReplaceAll_String_Same()
{
BString str("she sells sea shells on the seashore");
str.IReplaceAll("sea", "sea", 11);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells sea shells on the seashore"));
}
void IReplaceFirst_Char_Match()
{
BString str("test string");
str.IReplaceFirst('t', 'b');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "best string"));
}
void IReplaceFirst_Char_NoMatch()
{
BString str("test string");
str.IReplaceFirst('x', 'b');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "test string"));
}
void IReplaceLast_Char_Match()
{
BString str("test string");
str.IReplaceLast('t', 'w');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "test swring"));
}
void IReplaceLast_Char_NoMatch()
{
BString str("test string");
str.IReplaceLast('x', 'b');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "test string"));
}
void IReplaceAll_Char_Match()
{
BString str("TEST string");
str.IReplaceAll('t', 'i');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "iESi siring"));
}
void IReplaceAll_Char_Same()
{
BString str("TEST string");
str.IReplaceAll('t', 'T');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "TEST sTring"));
}
void IReplaceAll_Char_NoMatch()
{
BString str("test string");
str.IReplaceAll('x', 'b');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "test string"));
}
void IReplaceAll_Char_WithOffset()
{
BString str("TEST string");
str.IReplaceAll('t', 'i', 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "TESi siring"));
}
void IReplace_Char_InRange()
{
BString str("She sells Sea shells on the sea shore");
str.IReplace('s', 't', 4, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "She tellt tea thells on the sea shore"));
}
void IReplace_Char_NoMatchInRange()
{
BString str("She sells Sea shells on the sea shore");
str.IReplace('s', 's', 4, 2);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "She sells sea shells on the sea shore"));
}
void IReplace_Char_EmptyString()
{
BString str;
str.IReplace('s', 'x', 12, 32);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), ""));
}
void IReplaceFirst_String_MatchIgnoreCase()
{
BString str("she sells SeA shells on the seashore");
str.IReplaceFirst("sea", "the");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells the shells on the seashore"));
}
void IReplaceFirst_String_NoMatch()
{
BString str("she sells sea shells on the seashore");
str.IReplaceFirst("tex", "the");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells sea shells on the seashore"));
}
void IReplaceFirst_String_Null()
{
BString str("she sells SeA shells on the seashore");
str.IReplaceFirst("sea ", NULL);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells shells on the seashore"));
}
#ifndef TEST_R5
void IReplaceLast_String_MatchIgnoreCase()
{
BString str("she sells sea shells on the SEashore");
str.IReplaceLast("sea", "the");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells sea shells on the theshore"));
}
#endif
void IReplaceLast_String_NoMatch()
{
BString str("she sells sea shells on the seashore");
str.IReplaceLast("tex", "the");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells sea shells on the seashore"));
}
void IReplaceLast_String_Null()
{
BString str("she sells sea shells on the SEashore");
str.IReplaceLast("sea", NULL);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells sea shells on the shore"));
}
void IReplaceAll_String_MatchIgnoreCase()
{
BString str("abc ABc aBc");
str.IReplaceAll("ab", "abc");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "abcc abcc abcc"));
}
void IReplaceAll_String_NoMatch()
{
BString str("she sells sea shells on the seashore");
str.IReplaceAll("tex", "the");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells sea shells on the seashore"));
}
void IReplaceAll_String_MatchLengthy()
{
BString str("she sells SeA shells on the sEashore");
str.IReplaceAll("sea", "the", 11);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "she sells SeA shells on the theshore"));
}
void IReplaceAll_String_Null()
{
BString str("abc ABc aBc");
str.IReplaceAll("ab", NULL);
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "c c c"));
}
void ReplaceSet_Char_Single()
{
BString str("abc abc abc");
str.ReplaceSet("ab", 'x');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "xxc xxc xxc"));
}
void ReplaceSet_Char_Multiple()
{
BString str("abcabcabcbababc");
str.ReplaceSet("abc", 'c');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "ccccccccccccccc"));
}
void ReplaceSet_Char_Same()
{
BString str("abcabcabcbababc");
str.ReplaceSet("c", 'c');
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "abcabcabcbababc"));
}
#ifndef TEST_R5
void ReplaceSet_String_Match()
{
BString str("abcd abcd abcd");
str.ReplaceSet("abcd ", "");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), ""));
}
void ReplaceSet_String_Swap()
{
BString str("abcd abcd abcd");
str.ReplaceSet("ad", "da");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "dabcda dabcda dabcda"));
}
void ReplaceSet_String_Erase()
{
BString str("abcd abcd abcd");
str.ReplaceSet("ad", "");
CPPUNIT_ASSERT_EQUAL(0, strcmp(str.String(), "bc bc bc"));
}
#endif
void ReplaceSet_String_Perf1()
{
BString str;
int32 sz = 1024 * 50;
char* buf = str.LockBuffer(sz);
memset(buf, 'x', sz);
str.UnlockBuffer(sz);
str.ReplaceSet("x", "y");
CPPUNIT_ASSERT_EQUAL(sz, str.Length());
}
void ReplaceSet_String_Perf2()
{
BString str;
int32 sz = 1024 * 50;
char* buf = str.LockBuffer(sz);
memset(buf, 'x', sz);
str.UnlockBuffer(sz);
str.ReplaceSet("x", "");
CPPUNIT_ASSERT_EQUAL(0, str.Length());
}
void ReplaceAll_String_Perf1()
{
BString str;
int32 sz = 1024 * 50;
char* buf = str.LockBuffer(sz);
memset(buf, 'x', sz);
str.UnlockBuffer(sz);
str.ReplaceAll("x", "y");
CPPUNIT_ASSERT_EQUAL(sz, str.Length());
}
void ReplaceAll_String_Perf2()
{
BString str;
int32 sz = 1024 * 50;
char* buf = str.LockBuffer(sz);
memset(buf, 'x', sz);
str.UnlockBuffer(sz);
str.ReplaceAll("xx", "y");
CPPUNIT_ASSERT_EQUAL(sz / 2, str.Length());
}
void ReplaceSet_String_Perf3()
{
BString str;
int32 sz = 1024 * 50;
char* buf = str.LockBuffer(sz);
memset(buf, 'x', sz);
str.UnlockBuffer(sz);
str.ReplaceSet("xx", "");
CPPUNIT_ASSERT_EQUAL(0, str.Length());
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringReplaceTest, getTestSuiteName());
+657
View File
@@ -0,0 +1,657 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringSearchTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringSearchTest);
CPPUNIT_TEST(FindFirst_BString_Found);
CPPUNIT_TEST(FindFirst_BString_NotFound);
CPPUNIT_TEST(FindFirst_CString_Found);
CPPUNIT_TEST(FindFirst_CString_NotFound);
#ifndef TEST_R5
CPPUNIT_TEST(FindFirst_Null_ReturnsBadValue);
#endif
CPPUNIT_TEST(FindFirst_BString_ValidOffset_Found);
CPPUNIT_TEST(FindFirst_BString_OutOfBoundsOffset_NotFound);
CPPUNIT_TEST(FindFirst_BString_NegativeOffset_NotFound);
CPPUNIT_TEST(FindFirst_CString_ValidOffset_Found);
CPPUNIT_TEST(FindFirst_CString_OutOfBoundsOffset_NotFound);
CPPUNIT_TEST(FindFirst_CString_NegativeOffset_NotFound);
#ifndef TEST_R5
CPPUNIT_TEST(FindFirst_Null_ValidOffset_ReturnsBadValue);
#endif
CPPUNIT_TEST(FindFirst_Char_Found);
CPPUNIT_TEST(FindFirst_Char_NotFound);
CPPUNIT_TEST(FindFirst_CString_ValidOffset_Found_1);
CPPUNIT_TEST(FindFirst_Char_ValidOffset_NotFound);
CPPUNIT_TEST(FindFirst_CString_ValidOffset_NotFound);
#ifndef TEST_R5
CPPUNIT_TEST(StartsWith_BString_ReturnsTrue);
CPPUNIT_TEST(StartsWith_CString_ReturnsTrue);
CPPUNIT_TEST(StartsWith_CString_ValidOffset_ReturnsTrue);
#endif
CPPUNIT_TEST(FindLast_BString_Found);
CPPUNIT_TEST(FindLast_BString_NotFound);
CPPUNIT_TEST(FindLast_CString_Found);
CPPUNIT_TEST(FindLast_CString_NotFound);
#ifndef TEST_R5
CPPUNIT_TEST(FindLast_Null_ReturnsBadValue);
#endif
CPPUNIT_TEST(FindLast_BString_ValidOffset_Found);
CPPUNIT_TEST(FindLast_BString_NegativeOffset_NotFound);
CPPUNIT_TEST(FindLast_CString_ValidOffset_Found);
CPPUNIT_TEST(FindLast_CString_NegativeOffset_NotFound);
#ifndef TEST_R5
CPPUNIT_TEST(FindLast_Null_ValidOffset_ReturnsBadValue);
#endif
CPPUNIT_TEST(FindLast_Char_Found);
CPPUNIT_TEST(FindLast_Char_NotFound);
CPPUNIT_TEST(FindLast_CString_ValidOffset_Found_1);
CPPUNIT_TEST(FindLast_Char_ValidOffset_NotFound);
CPPUNIT_TEST(FindLast_Char_ValidOffset_Found);
CPPUNIT_TEST(FindLast_Char_ValidOffset_Found_1);
CPPUNIT_TEST(FindLast_CString_ValidOffset_NotFound);
CPPUNIT_TEST(IFindFirst_BString_Found);
CPPUNIT_TEST(IFindFirst_BString_Found_1);
CPPUNIT_TEST(IFindFirst_BString_NotFound);
CPPUNIT_TEST(IFindFirst_BString_Found_2);
CPPUNIT_TEST(IFindFirst_CString_Found);
CPPUNIT_TEST(IFindFirst_CString_Found_1);
CPPUNIT_TEST(IFindFirst_CString_NotFound);
#ifndef TEST_R5
CPPUNIT_TEST(IFindFirst_Null_ReturnsBadValue);
#endif
CPPUNIT_TEST(IFindFirst_BString_ValidOffset_Found);
CPPUNIT_TEST(IFindFirst_BString_ValidOffset_Found_1);
CPPUNIT_TEST(IFindFirst_BString_OutOfBoundsOffset_NotFound);
CPPUNIT_TEST(IFindFirst_BString_NegativeOffset_NotFound);
CPPUNIT_TEST(IFindFirst_CString_ValidOffset_Found);
CPPUNIT_TEST(IFindFirst_CString_ValidOffset_Found_1);
CPPUNIT_TEST(IFindFirst_CString_OutOfBoundsOffset_NotFound);
CPPUNIT_TEST(IFindFirst_CString_NegativeOffset_NotFound);
#ifndef TEST_R5
CPPUNIT_TEST(IStartsWith_BString_ReturnsTrue);
CPPUNIT_TEST(IStartsWith_CString_ReturnsTrue);
CPPUNIT_TEST(IStartsWith_CString_ValidOffset_ReturnsTrue);
CPPUNIT_TEST(IFindLast_BString_Found);
CPPUNIT_TEST(IFindLast_BString_Found_1);
CPPUNIT_TEST(EndsWith_BString_ReturnsTrue);
CPPUNIT_TEST(EndsWith_BString_ReturnsFalse);
CPPUNIT_TEST(EndsWith_CString_ReturnsTrue);
CPPUNIT_TEST(EndsWith_CString_ReturnsFalse);
CPPUNIT_TEST(EndsWith_CString_ValidOffset_ReturnsTrue);
CPPUNIT_TEST(EndsWith_CString_ValidOffset_ReturnsFalse);
CPPUNIT_TEST(IEndsWith_BString_ReturnsTrue);
CPPUNIT_TEST(IEndsWith_BString_ReturnsTrue_1);
CPPUNIT_TEST(IEndsWith_CString_ReturnsTrue);
CPPUNIT_TEST(IEndsWith_CString_ReturnsTrue_1);
CPPUNIT_TEST(IEndsWith_CString_ValidOffset_ReturnsTrue);
CPPUNIT_TEST(IEndsWith_CString_ValidOffset_ReturnsTrue_1);
#endif
CPPUNIT_TEST(IFindLast_BString_NotFound);
CPPUNIT_TEST(IFindLast_CString_Found);
CPPUNIT_TEST(IFindLast_CString_NotFound);
#ifndef TEST_R5
CPPUNIT_TEST(IFindLast_CString_Found_1);
CPPUNIT_TEST(IFindLast_Null_ReturnsBadValue);
CPPUNIT_TEST(IFindLast_CString_ValidOffset_Found_1);
#endif
CPPUNIT_TEST(IFindLast_BString_ValidOffset_Found);
CPPUNIT_TEST(IFindLast_BString_ValidOffset_Found_1);
CPPUNIT_TEST(IFindLast_BString_NegativeOffset_NotFound);
CPPUNIT_TEST(IFindLast_CString_ValidOffset_Found);
CPPUNIT_TEST(IFindLast_CString_NegativeOffset_NotFound);
CPPUNIT_TEST(IFindLast_CString_ValidOffset_Found_2);
CPPUNIT_TEST_SUITE_END();
public:
void FindFirst_BString_Found()
{
BString string1("last but not least");
BString string2("st");
CPPUNIT_ASSERT_EQUAL(2, string1.FindFirst(string2));
}
void FindFirst_BString_NotFound()
{
BString string1;
BString string2("some text");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindFirst(string2));
}
void FindFirst_CString_Found()
{
BString string1("last but not least");
CPPUNIT_ASSERT_EQUAL(2, string1.FindFirst("st"));
}
void FindFirst_CString_NotFound()
{
BString string1;
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindFirst("some text"));
}
#ifndef TEST_R5
void FindFirst_Null_ReturnsBadValue()
{
BString string1("string");
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, string1.FindFirst((char*)NULL));
}
#endif
void FindFirst_BString_ValidOffset_Found()
{
BString string1("abc abc abc");
BString string2("abc");
CPPUNIT_ASSERT_EQUAL(8, string1.FindFirst(string2, 5));
}
void FindFirst_BString_OutOfBoundsOffset_NotFound()
{
BString string1("abc abc abc");
BString string2("abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindFirst(string2, 200));
}
void FindFirst_BString_NegativeOffset_NotFound()
{
BString string1("abc abc abc");
BString string2("abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindFirst(string2, -10));
}
void FindFirst_CString_ValidOffset_Found()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(4, string1.FindFirst("abc", 2));
}
void FindFirst_CString_OutOfBoundsOffset_NotFound()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindFirst("abc", 200));
}
void FindFirst_CString_NegativeOffset_NotFound()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindFirst("abc", -10));
}
#ifndef TEST_R5
void FindFirst_Null_ValidOffset_ReturnsBadValue()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, string1.FindFirst((char*)NULL, 3));
}
#endif
void FindFirst_Char_Found()
{
BString string1("abcd abcd");
CPPUNIT_ASSERT_EQUAL(2, string1.FindFirst('c'));
}
void FindFirst_Char_NotFound()
{
BString string1("abcd abcd");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindFirst('e'));
}
void FindFirst_CString_ValidOffset_Found_1()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(5, string1.FindFirst("b", 3));
}
void FindFirst_Char_ValidOffset_NotFound()
{
BString string1("abcd abcd");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindFirst('e', 3));
}
void FindFirst_CString_ValidOffset_NotFound()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindFirst("a", 9));
}
#ifndef TEST_R5
void StartsWith_BString_ReturnsTrue()
{
BString string1("last but not least");
BString string2("last");
CPPUNIT_ASSERT(string1.StartsWith(string2));
}
void StartsWith_CString_ReturnsTrue()
{
BString string1("last but not least");
CPPUNIT_ASSERT(string1.StartsWith("last"));
}
void StartsWith_CString_ValidOffset_ReturnsTrue()
{
BString string1("last but not least");
CPPUNIT_ASSERT(string1.StartsWith("last", 4));
}
#endif
void FindLast_BString_Found()
{
BString string1("last but not least");
BString string2("st");
CPPUNIT_ASSERT_EQUAL(16, string1.FindLast(string2));
}
void FindLast_BString_NotFound()
{
BString string1;
BString string2("some text");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindLast(string2));
// FindLast(char*)
}
void FindLast_CString_Found()
{
BString string1("last but not least");
CPPUNIT_ASSERT_EQUAL(16, string1.FindLast("st"));
}
void FindLast_CString_NotFound()
{
BString string1;
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindLast("some text"));
}
#ifndef TEST_R5
void FindLast_Null_ReturnsBadValue()
{
BString string1("string");
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, string1.FindLast((char*)NULL));
}
#endif
void FindLast_BString_ValidOffset_Found()
{
BString string1("abcabcabc");
BString string2("abc");
CPPUNIT_ASSERT_EQUAL(3, string1.FindLast(string2, 7));
}
void FindLast_BString_NegativeOffset_NotFound()
{
BString string1("abc abc abc");
BString string2("abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindLast(string2, -10));
// FindLast(const char*, int32)
}
void FindLast_CString_ValidOffset_Found()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(4, string1.FindLast("abc", 9));
}
void FindLast_CString_NegativeOffset_NotFound()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindLast("abc", -10));
}
#ifndef TEST_R5
void FindLast_Null_ValidOffset_ReturnsBadValue()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, string1.FindLast((char*)NULL, 3));
}
#endif
void FindLast_Char_Found()
{
BString string1("abcd abcd");
CPPUNIT_ASSERT_EQUAL(7, string1.FindLast('c'));
}
void FindLast_Char_NotFound()
{
BString string1("abcd abcd");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindLast('e'));
}
void FindLast_CString_ValidOffset_Found_1()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(1, string1.FindLast("b", 5));
}
void FindLast_Char_ValidOffset_NotFound()
{
BString string1("abcd abcd");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindLast('e', 3));
}
void FindLast_Char_ValidOffset_Found()
{
BString string1("abcd abcd");
CPPUNIT_ASSERT_EQUAL(6, string1.FindLast('b', 6));
}
void FindLast_Char_ValidOffset_Found_1()
{
BString string1("abcd abcd");
CPPUNIT_ASSERT_EQUAL(1, string1.FindLast('b', 5));
}
void FindLast_CString_ValidOffset_NotFound()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.FindLast("a", 0));
}
void IFindFirst_BString_Found()
{
BString string1("last but not least");
BString string2("st");
CPPUNIT_ASSERT_EQUAL(2, string1.IFindFirst(string2));
}
void IFindFirst_BString_Found_1()
{
BString string1("last but not least");
BString string2("ST");
CPPUNIT_ASSERT_EQUAL(2, string1.IFindFirst(string2));
}
void IFindFirst_BString_NotFound()
{
BString string1;
BString string2("some text");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.IFindFirst(string2));
}
void IFindFirst_BString_Found_2()
{
BString string1("string");
BString string2;
CPPUNIT_ASSERT_EQUAL(0, string1.IFindFirst(string2));
}
void IFindFirst_CString_Found()
{
BString string1("last but not least");
CPPUNIT_ASSERT_EQUAL(2, string1.IFindFirst("st"));
}
void IFindFirst_CString_Found_1()
{
BString string1("LAST BUT NOT least");
CPPUNIT_ASSERT_EQUAL(2, string1.IFindFirst("st"));
}
void IFindFirst_CString_NotFound()
{
BString string1;
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.IFindFirst("some text"));
}
#ifndef TEST_R5
void IFindFirst_Null_ReturnsBadValue()
{
BString string1("string");
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, string1.IFindFirst((char*)NULL));
}
#endif
void IFindFirst_BString_ValidOffset_Found()
{
BString string1("abc abc abc");
BString string2("abc");
CPPUNIT_ASSERT_EQUAL(8, string1.IFindFirst(string2, 5));
}
void IFindFirst_BString_ValidOffset_Found_1()
{
BString string1("abc abc abc");
BString string2("AbC");
CPPUNIT_ASSERT_EQUAL(8, string1.IFindFirst(string2, 5));
}
void IFindFirst_BString_OutOfBoundsOffset_NotFound()
{
BString string1("abc abc abc");
BString string2("abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.IFindFirst(string2, 200));
}
void IFindFirst_BString_NegativeOffset_NotFound()
{
BString string1("abc abc abc");
BString string2("abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.IFindFirst(string2, -10));
}
void IFindFirst_CString_ValidOffset_Found()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(4, string1.IFindFirst("abc", 2));
}
void IFindFirst_CString_ValidOffset_Found_1()
{
BString string1("AbC ABC abC");
CPPUNIT_ASSERT_EQUAL(4, string1.IFindFirst("abc", 2));
}
void IFindFirst_CString_OutOfBoundsOffset_NotFound()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.IFindFirst("abc", 200));
}
void IFindFirst_CString_NegativeOffset_NotFound()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.IFindFirst("abc", -10));
}
#ifndef TEST_R5
void IStartsWith_BString_ReturnsTrue()
{
BString string1("last but not least");
BString string2("lAsT");
CPPUNIT_ASSERT(string1.IStartsWith(string2));
}
void IStartsWith_CString_ReturnsTrue()
{
BString string1("last but not least");
CPPUNIT_ASSERT(string1.IStartsWith("lAsT"));
}
void IStartsWith_CString_ValidOffset_ReturnsTrue()
{
BString string1("last but not least");
CPPUNIT_ASSERT(string1.IStartsWith("lAsT", 4));
}
void IFindLast_BString_Found()
{
BString string1("last but not least");
BString string2("st");
CPPUNIT_ASSERT_EQUAL(16, string1.IFindLast(string2));
}
void IFindLast_BString_Found_1()
{
BString string1("laSt but NOT leaSt");
BString string2("sT");
CPPUNIT_ASSERT_EQUAL(16, string1.IFindLast(string2));
}
void EndsWith_BString_ReturnsTrue()
{
BString string1("last but not least");
BString string2("st");
CPPUNIT_ASSERT(string1.EndsWith(string2));
}
void EndsWith_BString_ReturnsFalse()
{
BString string1("laSt but NOT leaSt");
BString string2("sT");
CPPUNIT_ASSERT_EQUAL(0, string1.EndsWith(string2));
}
void EndsWith_CString_ReturnsTrue()
{
BString string1("last but not least");
CPPUNIT_ASSERT(string1.EndsWith("least"));
}
void EndsWith_CString_ReturnsFalse()
{
BString string1("laSt but NOT leaSt");
CPPUNIT_ASSERT_EQUAL(0, string1.EndsWith("least"));
}
void EndsWith_CString_ValidOffset_ReturnsTrue()
{
BString string1("last but not least");
CPPUNIT_ASSERT(string1.EndsWith("st", 2));
}
void EndsWith_CString_ValidOffset_ReturnsFalse()
{
BString string1("laSt but NOT leaSt");
CPPUNIT_ASSERT_EQUAL(0, string1.EndsWith("sT", 2));
}
void IEndsWith_BString_ReturnsTrue()
{
BString string1("last but not least");
BString string2("st");
CPPUNIT_ASSERT(string1.IEndsWith(string2));
}
void IEndsWith_BString_ReturnsTrue_1()
{
BString string1("laSt but NOT leaSt");
BString string2("sT");
CPPUNIT_ASSERT(string1.IEndsWith(string2));
}
void IEndsWith_CString_ReturnsTrue()
{
BString string1("last but not least");
CPPUNIT_ASSERT(string1.IEndsWith("st"));
}
void IEndsWith_CString_ReturnsTrue_1()
{
BString string1("laSt but NOT leaSt");
CPPUNIT_ASSERT(string1.IEndsWith("sT"));
}
void IEndsWith_CString_ValidOffset_ReturnsTrue()
{
BString string1("last but not least");
CPPUNIT_ASSERT(string1.IEndsWith("st", 2));
}
void IEndsWith_CString_ValidOffset_ReturnsTrue_1()
{
BString string1("laSt but NOT leaSt");
CPPUNIT_ASSERT(string1.IEndsWith("sT", 2));
}
#endif
void IFindLast_BString_NotFound()
{
BString string1;
BString string2("some text");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.IFindLast(string2));
}
void IFindLast_CString_Found()
{
BString string1("last but not least");
CPPUNIT_ASSERT_EQUAL(16, string1.IFindLast("st"));
}
void IFindLast_CString_NotFound()
{
BString string1;
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.IFindLast("some text"));
}
#ifndef TEST_R5
void IFindLast_CString_Found_1()
{
BString string1("laSt but NOT leaSt");
CPPUNIT_ASSERT_EQUAL(16, string1.IFindLast("ST"));
}
void IFindLast_Null_ReturnsBadValue()
{
BString string1("string");
CPPUNIT_ASSERT_EQUAL(B_BAD_VALUE, string1.IFindLast((char*)NULL));
}
void IFindLast_CString_ValidOffset_Found_1()
{
BString string1("ABc abC aBC");
CPPUNIT_ASSERT_EQUAL(4, string1.IFindLast("aBc", 9));
}
#endif
void IFindLast_BString_ValidOffset_Found()
{
BString string1("abcabcabc");
BString string2("abc");
CPPUNIT_ASSERT_EQUAL(3, string1.IFindLast(string2, 7));
}
void IFindLast_BString_ValidOffset_Found_1()
{
BString string1("abcabcabc");
BString string2("AbC");
CPPUNIT_ASSERT_EQUAL(3, string1.IFindLast(string2, 7));
}
void IFindLast_BString_NegativeOffset_NotFound()
{
BString string1("abc abc abc");
BString string2("abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.IFindLast(string2, -10));
}
void IFindLast_CString_ValidOffset_Found()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(4, string1.IFindLast("abc", 9));
}
void IFindLast_CString_NegativeOffset_NotFound()
{
BString string1("abc abc abc");
CPPUNIT_ASSERT_EQUAL(B_ERROR, string1.IFindLast("abc", -10));
}
void IFindLast_CString_ValidOffset_Found_2()
{
BString string1("abc def ghi");
CPPUNIT_ASSERT_EQUAL(0, string1.IFindLast("abc", 4));
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringSearchTest, getTestSuiteName());
@@ -0,0 +1,58 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <StringList.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringSplitTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringSplitTest);
CPPUNIT_TEST(SingleCharIgnoreEmpty_SplitsCorrectly);
CPPUNIT_TEST(StringIgnoreEmpty_SplitsCorrectly);
CPPUNIT_TEST(StringKeepEmpty_SplitsCorrectly);
CPPUNIT_TEST(SingleCharKeepEmpty_SplitsCorrectly);
CPPUNIT_TEST_SUITE_END();
public:
void SingleCharIgnoreEmpty_SplitsCorrectly()
{
BString str1("test::string");
BStringList stringList1;
str1.Split(":", true, stringList1);
CPPUNIT_ASSERT_EQUAL(2, stringList1.CountStrings());
}
void StringIgnoreEmpty_SplitsCorrectly()
{
BString str1("test::string");
BStringList stringList2;
str1.Split("::", true, stringList2);
CPPUNIT_ASSERT_EQUAL(2, stringList2.CountStrings());
}
void StringKeepEmpty_SplitsCorrectly()
{
BString str1("test::string");
BStringList stringList3;
str1.Split("::", false, stringList3);
CPPUNIT_ASSERT_EQUAL(2, stringList3.CountStrings());
}
void SingleCharKeepEmpty_SplitsCorrectly()
{
BString str1("test::string");
BStringList stringList4;
str1.Split(":", false, stringList4);
CPPUNIT_ASSERT_EQUAL(3, stringList4.CountStrings());
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringSplitTest, getTestSuiteName());
@@ -0,0 +1,41 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringSubCopyTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringSubCopyTest);
CPPUNIT_TEST(BString_CopiesSubstring);
CPPUNIT_TEST(CString_CopiesSubstring);
CPPUNIT_TEST_SUITE_END();
public:
void BString_CopiesSubstring()
{
BString string1;
BString string2("Something");
string2.CopyInto(string1, 4, 30);
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "thing"));
}
void CString_CopiesSubstring()
{
char tmp[10];
memset(tmp, 0, 10);
BString string1("ABC");
string1.CopyInto(tmp, 0, 4);
CPPUNIT_ASSERT_EQUAL(0, strcmp(tmp, "ABC"));
CPPUNIT_ASSERT_EQUAL(0, strcmp(string1.String(), "ABC"));
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringSubCopyTest, getTestSuiteName());
+141
View File
@@ -0,0 +1,141 @@
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <String.h>
#include <UTF8.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
class StringUTF8Test : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringUTF8Test);
CPPUNIT_TEST(LengthAndCountChars_UTF8String_ReturnsCorrectValues);
CPPUNIT_TEST(ReplaceCharsSet_UTF8String_ReplacesChars);
CPPUNIT_TEST(MoveCharsInto_UTF8String_MovesCharsAndLeavesEllipsis);
CPPUNIT_TEST(RemoveCharsSet_UTF8String_RemovesSpecifiedChars);
CPPUNIT_TEST(SetToChars_UTF8String_SetsStringCorrectly);
CPPUNIT_TEST(TruncateChars_UTF8String_TruncatesString);
CPPUNIT_TEST(AppendChars_UTF8String_AppendsCharsCorrectly);
CPPUNIT_TEST(RemoveChars_UTF8String_RemovesCharsCorrectly);
CPPUNIT_TEST(InsertChars_UTF8String_InsertsCharsCorrectly);
CPPUNIT_TEST(PrependChars_UTF8String_PrependsCharsCorrectly);
CPPUNIT_TEST(CompareChars_UTF8String_ComparesCorrectly);
CPPUNIT_TEST(CountBytes_UTF8String_CountsBytesCorrectly);
CPPUNIT_TEST_SUITE_END();
public:
void LengthAndCountChars_UTF8String_ReturnsCorrectValues()
{
BString string("ü-ä-ö");
CPPUNIT_ASSERT_EQUAL(8, string.Length());
CPPUNIT_ASSERT_EQUAL(5, string.CountChars());
CPPUNIT_ASSERT_EQUAL(0, memcmp(string.String(), "ü-ä-ö", 8));
}
void ReplaceCharsSet_UTF8String_ReplacesChars()
{
BString string("ü-ä-ö");
string.ReplaceCharsSet("üö", B_UTF8_ELLIPSIS);
CPPUNIT_ASSERT_EQUAL(10, string.Length());
CPPUNIT_ASSERT_EQUAL(5, string.CountChars());
CPPUNIT_ASSERT_EQUAL(0, memcmp(string.String(), B_UTF8_ELLIPSIS "-ä-" B_UTF8_ELLIPSIS, 10));
}
void MoveCharsInto_UTF8String_MovesCharsAndLeavesEllipsis()
{
BString string(B_UTF8_ELLIPSIS "-ä-" B_UTF8_ELLIPSIS);
BString ellipsis;
string.MoveCharsInto(ellipsis, 4, 1);
CPPUNIT_ASSERT_EQUAL(7, string.Length());
CPPUNIT_ASSERT_EQUAL(4, string.CountChars());
CPPUNIT_ASSERT_EQUAL(0, memcmp(string.String(), B_UTF8_ELLIPSIS "-ä-", 7));
CPPUNIT_ASSERT_EQUAL(3, ellipsis.Length());
CPPUNIT_ASSERT_EQUAL(1, ellipsis.CountChars());
CPPUNIT_ASSERT_EQUAL(0, memcmp(ellipsis.String(), B_UTF8_ELLIPSIS, 3));
}
void RemoveCharsSet_UTF8String_RemovesSpecifiedChars()
{
BString string(B_UTF8_ELLIPSIS "-ä-");
string.RemoveCharsSet("-" B_UTF8_ELLIPSIS);
CPPUNIT_ASSERT_EQUAL(2, string.Length());
CPPUNIT_ASSERT_EQUAL(1, string.CountChars());
CPPUNIT_ASSERT_EQUAL(0, memcmp(string.String(), "ä", 2));
}
void SetToChars_UTF8String_SetsStringCorrectly()
{
BString string("ä");
string.SetToChars("öäü" B_UTF8_ELLIPSIS "öäü", 5);
CPPUNIT_ASSERT_EQUAL(11, string.Length());
CPPUNIT_ASSERT_EQUAL(5, string.CountChars());
CPPUNIT_ASSERT_EQUAL(0, memcmp(string.String(), "öäü" B_UTF8_ELLIPSIS "ö", 11));
}
void TruncateChars_UTF8String_TruncatesString()
{
BString string("öäü" B_UTF8_ELLIPSIS "ö");
string.TruncateChars(4);
CPPUNIT_ASSERT_EQUAL(9, string.Length());
CPPUNIT_ASSERT_EQUAL(4, string.CountChars());
CPPUNIT_ASSERT_EQUAL(0, memcmp(string.String(), "öäü" B_UTF8_ELLIPSIS, 9));
}
void AppendChars_UTF8String_AppendsCharsCorrectly()
{
BString string("öäü" B_UTF8_ELLIPSIS);
string.AppendChars("öäü", 2);
CPPUNIT_ASSERT_EQUAL(13, string.Length());
CPPUNIT_ASSERT_EQUAL(6, string.CountChars());
CPPUNIT_ASSERT_EQUAL(0, memcmp(string.String(), "öäü" B_UTF8_ELLIPSIS "öä", 13));
}
void RemoveChars_UTF8String_RemovesCharsCorrectly()
{
BString string("öäü" B_UTF8_ELLIPSIS "öä");
string.RemoveChars(1, 3);
CPPUNIT_ASSERT_EQUAL(6, string.Length());
CPPUNIT_ASSERT_EQUAL(3, string.CountChars());
CPPUNIT_ASSERT_EQUAL(0, memcmp(string.String(), "ööä", 6));
}
void InsertChars_UTF8String_InsertsCharsCorrectly()
{
BString string("ööä");
string.InsertChars("öäü" B_UTF8_ELLIPSIS B_UTF8_ELLIPSIS "ä", 3, 2, 1);
CPPUNIT_ASSERT_EQUAL(12, string.Length());
CPPUNIT_ASSERT_EQUAL(5, string.CountChars());
CPPUNIT_ASSERT_EQUAL(0, memcmp(string.String(), "ö" B_UTF8_ELLIPSIS B_UTF8_ELLIPSIS "öä", 12));
}
void PrependChars_UTF8String_PrependsCharsCorrectly()
{
BString string("ö" B_UTF8_ELLIPSIS B_UTF8_ELLIPSIS "öä");
string.PrependChars("ää+üü", 3);
CPPUNIT_ASSERT_EQUAL(17, string.Length());
CPPUNIT_ASSERT_EQUAL(8, string.CountChars());
CPPUNIT_ASSERT_EQUAL(0, memcmp(string.String(), "ää+ö" B_UTF8_ELLIPSIS B_UTF8_ELLIPSIS "öä", 17));
}
void CompareChars_UTF8String_ComparesCorrectly()
{
BString string("ää+ö" B_UTF8_ELLIPSIS B_UTF8_ELLIPSIS "öä");
const char* compare = "ää+ö" B_UTF8_ELLIPSIS "different";
CPPUNIT_ASSERT(string.CompareChars(compare, 5) == 0);
CPPUNIT_ASSERT(string.CompareChars(compare, 6) != 0);
}
void CountBytes_UTF8String_CountsBytesCorrectly()
{
BString string("ää+ö" B_UTF8_ELLIPSIS B_UTF8_ELLIPSIS "öä");
CPPUNIT_ASSERT_EQUAL(6, string.CountBytes(2, 3));
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StringUTF8Test, getTestSuiteName());
+9 -31
View File
@@ -1,36 +1,14 @@
#include <TestSuite.h>
/*
* Copyright 2002-2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <TestSuiteAddon.h>
// ##### Include headers for your tests here #####
#include "barchivable/ArchivableTest.h"
#include "bautolock/AutolockTest.h"
#include "blocker/LockerTest.h"
#include "bmemoryio/MemoryIOTest.h"
#include "bmemoryio/MallocIOTest.h"
#include "bstring/StringTest.h"
#include "bblockcache/BlockCacheTest.h"
#include "bstopwatch/BStopWatchTest.h"
const char* getTestSuiteName() {
const char*
getTestSuiteName()
{
return "SupportKit";
}
BTestSuite *
getTestSuite()
{
BTestSuite *suite = new BTestSuite("Support");
// ##### Add test suites here #####
suite->addTest("BArchivable", ArchivableTestSuite());
suite->addTest("BAutolock", AutolockTestSuite());
suite->addTest("BLocker", LockerTestSuite());
suite->addTest("BMemoryIO", MemoryIOTestSuite());
suite->addTest("BMallocIO", MallocIOTestSuite());
suite->addTest("BString", StringTestSuite());
suite->addTest("BBlockCache", BlockCacheTestSuite());
suite->addTest("BStopWatch", BStopWatchTestSuite());
return suite;
}
@@ -1,25 +0,0 @@
/*
$Id:
*/
#include "BArchivableTester.h"
#include "ValidateInstantiationTester.h"
#include "InstantiateObjectTester.h"
#include "FindInstantiationFuncTester.h"
#include "ArchivableTest.h"
#include "cppunit/Test.h"
#include "cppunit/TestSuite.h"
CppUnit::Test* ArchivableTestSuite()
{
CppUnit::TestSuite *testSuite = new CppUnit::TestSuite();
testSuite->addTest(TBArchivableTestCase::Suite());
testSuite->addTest(TValidateInstantiationTest::Suite());
// testSuite->addTest(TInstantiateObjectTester::Suite());
testSuite->addTest(TFindInstantiationFuncTester::Suite());
return testSuite;
}
@@ -1,9 +0,0 @@
#ifndef _archivable_test_file_h_
#define _archivable_test_file_h_
class CppUnit::Test;
CppUnit::Test* ArchivableTestSuite();
#endif // _locker_test_h_
@@ -1,133 +0,0 @@
//------------------------------------------------------------------------------
// BArchivableTester.cpp
//
/**
BArchivable tests
@note InvalidArchiveShallow() and InvalidArchiveDeep() are not tested
against the original implementation as it does not handle NULL
parameters gracefully.
*/
//------------------------------------------------------------------------------
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
#include <Message.h>
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
#include "BArchivableTester.h"
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
//------------------------------------------------------------------------------
/**
BArchivable::Perform(perform_code d, void* arg)
@case Any
@param d Not used
@param arg Not used
@results Returns B_ERROR in all cases.
*/
void TBArchivableTestCase::TestPerform()
{
BArchivable Archive;
CPPUNIT_ASSERT(Archive.Perform(0, NULL) == B_ERROR);
}
//------------------------------------------------------------------------------
/**
BArchivable::Archive(BMessage* into, bool deep)
@case Invalid archive, shallow archiving
@param into NULL
@param deep false
@results Returns B_BAD_VALUE.
*/
void TBArchivableTestCase::InvalidArchiveShallow()
{
BArchivable Archive;
CPPUNIT_ASSERT(Archive.Archive(NULL, false) == B_BAD_VALUE);
}
//------------------------------------------------------------------------------
/**
BArchivable::Archive(BMessage* into, bool deep)
@case Valid archive, shallow archiving
@param into Valid BMessage pointer
@param deep false
@results Returns B_OK.
Resultant archive has a string field labeled "class".
Field "class" contains the string "BArchivable".
*/
#include <stdio.h>
#include <Debug.h>
void TBArchivableTestCase::ValidArchiveShallow()
{
BMessage Storage;
BArchivable Archive;
CPPUNIT_ASSERT(Archive.Archive(&Storage, false) == B_OK);
const char* name;
CPPUNIT_ASSERT(Storage.FindString("class", &name) == B_OK);
printf("\n%s\n", name);
CPPUNIT_ASSERT(strcmp(name, "BArchivable") == 0);
}
//------------------------------------------------------------------------------
/**
BArchivable::Archive(BMessage* into, bool deep)
@case Invalid archive, deep archiving
@param into NULL
@param deep true
@results Returns B_BAD_VALUE
*/
void TBArchivableTestCase::InvalidArchiveDeep()
{
BArchivable Archive;
CPPUNIT_ASSERT(Archive.Archive(NULL, true) == B_BAD_VALUE);
}
//------------------------------------------------------------------------------
/**
BArchivable::Archive(BMessage* into, bool deep)
@case Valid archive, deep archiving
@param into Valid BMessage pointer
@param deep true
@results Returns B_OK.
Resultant archive has a string field labeled "class".
Field "class" contains the string "BArchivable".
*/
void TBArchivableTestCase::ValidArchiveDeep()
{
BMessage Storage;
BArchivable Archive;
CPPUNIT_ASSERT(Archive.Archive(&Storage, true) == B_OK);
const char* name;
CPPUNIT_ASSERT(Storage.FindString("class", &name) == B_OK);
CPPUNIT_ASSERT(strcmp(name, "BArchivable") == 0);
}
//------------------------------------------------------------------------------
CppUnit::Test* TBArchivableTestCase::Suite()
{
CppUnit::TestSuite* SuiteOfTests = new CppUnit::TestSuite;
// ADD_TEST(SuiteOfTests, TBArchivableTestCase, TestPerform);
#if !defined(TEST_R5)
ADD_TEST(SuiteOfTests, TBArchivableTestCase, InvalidArchiveShallow);
#endif
ADD_TEST(SuiteOfTests, TBArchivableTestCase, ValidArchiveShallow);
#if !defined(TEST_R5)
ADD_TEST(SuiteOfTests, TBArchivableTestCase, InvalidArchiveDeep);
#endif
ADD_TEST(SuiteOfTests, TBArchivableTestCase, ValidArchiveDeep);
return SuiteOfTests;
}
//------------------------------------------------------------------------------
/*
* $Log $
*
* $Id $
*
*/
@@ -1,46 +0,0 @@
//------------------------------------------------------------------------------
// BArchivableTester.h
//
//------------------------------------------------------------------------------
#ifndef BARCHIVABLETESTER_H
#define BARCHIVABLETESTER_H
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
#include "LocalCommon.h"
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
class TBArchivableTestCase : public BTestCase
{
public:
TBArchivableTestCase(std::string name = "") : BTestCase(name) {;}
void TestPerform();
void InvalidArchiveShallow();
void ValidArchiveShallow();
void InvalidArchiveDeep();
void ValidArchiveDeep();
static CppUnit::Test* Suite();
};
#endif //BARCHIVABLETESTER_H
/*
* $Log $
*
* $Id $
*
*/
@@ -1,399 +0,0 @@
//------------------------------------------------------------------------------
// FindInstatiationFuncTester.cpp
//
/**
Tests for find_instantiation_func(const char* name, const char* sig)
@note There are no tests for find_instantiation_func(const char*) as it
simply calls through to the version which takes an explicit sig,
setting that parameter to NULL.
Here's the use case matrix:
name sig
-------- --------
case 1 NULL NULL
case 2 bogus NULL
case 3 NULL bogus
case 4 bogus bogus
case 5 local NULL
case 6 remote NULL
case 7 local bogus
case 8 remote bogus
case 9 local good
case 10 remote good
*/
//------------------------------------------------------------------------------
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
#include "FindInstantiationFuncTester.h"
#include "LocalTestObject.h"
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Both parameters NULL
@param name NULL
@param sig NULL
@results Returns NULL
*/
void TFindInstantiationFuncTester::Case1()
{
instantiation_func f = find_instantiation_func(NULL, NULL);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Bad name with NULL signature
@param name Invalid class name
@param sig NULL
@results Returns NULL
*/
void TFindInstantiationFuncTester::Case2()
{
instantiation_func f = find_instantiation_func(gInvalidClassName, NULL);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case NULL name with invalid signature
@param name NULL class name
@param sig Invalid signature
@results Returns NULL
*/
void TFindInstantiationFuncTester::Case3()
{
instantiation_func f = find_instantiation_func(NULL, gInvalidSig);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Both params are invalid
@param name Invalid class name
@param sig Invalid signature
@results Returns NULL
*/
void TFindInstantiationFuncTester::Case4()
{
instantiation_func f = find_instantiation_func(gInvalidClassName,
gInvalidSig);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Valid name of a locally implemented class with a
NULL signature
@param name Valid local class name
@param sig NULL signature
@results Returns valid function
*/
void TFindInstantiationFuncTester::Case5()
{
instantiation_func f = find_instantiation_func(gLocalClassName, NULL);
CPPUNIT_ASSERT(f != NULL);
BMessage Archive;
Archive.AddString("class", gLocalClassName);
TIOTest* Test = dynamic_cast<TIOTest*>(f(&Archive));
CPPUNIT_ASSERT(Test != NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Valid name of a remotely implemented class with a
NULL signature
@param name Valid remote class name
@param sig NULL signature
@results Returns NULL
*/
void TFindInstantiationFuncTester::Case6()
{
instantiation_func f = find_instantiation_func(gRemoteClassName, NULL);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Valid name of a locally implemented class with an
invalid signature
@param name Valid local class name
@param sig Invalid signature
@results Returns NULL
*/
void TFindInstantiationFuncTester::Case7()
{
instantiation_func f = find_instantiation_func(gLocalClassName,
gInvalidSig);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Valid name of a remotely implemented class with an
invalid signature
@param name Valid remote class name
@param sig Invalid signature
@results Returns NULL
*/
void TFindInstantiationFuncTester::Case8()
{
instantiation_func f = find_instantiation_func(gRemoteClassName,
gInvalidSig);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Valid name of a locally implemented class with a
valid signature
@param name Valid local class name
@param sig Valid signature
@results Returns valid function
@note This test is not currently used; can't obtain the local
signature without a BApplication object (gLocalSig is a
placeholder).
*/
void TFindInstantiationFuncTester::Case9()
{
instantiation_func f = find_instantiation_func(gLocalClassName, gLocalSig);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Valid name of a remotely implemented class with a
valid signature
@param name Valid remote class name
@param sig Valid signature
@results Returns NULL
@note This case's results are because find_instantiation_func
doesn't actually load anything in order to do its work.
*/
void TFindInstantiationFuncTester::Case10()
{
instantiation_func f = find_instantiation_func(gRemoteClassName,
gRemoteSig);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Archive is NULL
@param Archive NULL
*/
void TFindInstantiationFuncTester::Case1M()
{
instantiation_func f = find_instantiation_func((BMessage*)NULL);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Bad name with NULL signature
@param name Invalid class name
@param sig NULL
@results Returns NULL
*/
void TFindInstantiationFuncTester::Case2M()
{
BMessage Archive;
Archive.AddString("class", gInvalidClassName);
instantiation_func f = find_instantiation_func(&Archive);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case NULL name with invalid signature
@param name NULL class name
@param sig Invalid signature
@results Returns NULL
*/
void TFindInstantiationFuncTester::Case3M()
{
BMessage Archive;
Archive.AddString("add_on", gInvalidSig);
instantiation_func f = find_instantiation_func(&Archive);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Both params are invalid
@param name Invalid class name
@param sig Invalid signature
@results Returns NULL
*/
void TFindInstantiationFuncTester::Case4M()
{
BMessage Archive;
Archive.AddString("class", gInvalidClassName);
Archive.AddString("add_on", gInvalidSig);
instantiation_func f = find_instantiation_func(&Archive);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Valid name of a locally implemented class with a
NULL signature
@param name Valid local class name
@param sig NULL signature
@results Returns valid function
*/
void TFindInstantiationFuncTester::Case5M()
{
BMessage Archive;
Archive.AddString("class", gLocalClassName);
instantiation_func f = find_instantiation_func(&Archive);
CPPUNIT_ASSERT(f != NULL);
TIOTest* Test = dynamic_cast<TIOTest*>(f(&Archive));
CPPUNIT_ASSERT(Test != NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Valid name of a remotely implemented class with a
NULL signature
@param name Valid remote class name
@param sig NULL signature
@results Returns NULL
*/
void TFindInstantiationFuncTester::Case6M()
{
BMessage Archive;
Archive.AddString("class", gRemoteClassName);
instantiation_func f = find_instantiation_func(&Archive);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Valid name of a locally implemented class with an
invalid signature
@param name Valid local class name
@param sig Invalid signature
@results Returns NULL
*/
void TFindInstantiationFuncTester::Case7M()
{
BMessage Archive;
Archive.AddString("class", gLocalClassName);
Archive.AddString("add_on", gInvalidSig);
instantiation_func f = find_instantiation_func(&Archive);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Valid name of a remotely implemented class with an
invalid signature
@param name Valid remote class name
@param sig Invalid signature
@results Returns NULL
*/
void TFindInstantiationFuncTester::Case8M()
{
BMessage Archive;
Archive.AddString("class", gRemoteClassName);
Archive.AddString("add_on", gInvalidSig);
instantiation_func f = find_instantiation_func(&Archive);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Valid name of a locally implemented class with a
valid signature
@param name Valid local class name
@param sig Valid signature
@results Returns valid function
@note This test is not currently used; can't obtain the local
signature without a BApplication object (gLocalSig is a
placeholder).
*/
void TFindInstantiationFuncTester::Case9M()
{
BMessage Archive;
Archive.AddString("class", gLocalClassName);
Archive.AddString("add_on", gLocalSig);
instantiation_func f = find_instantiation_func(&Archive);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
/**
find_instantiation_func(const char* name, const char* sig)
@case Valid name of a remotely implemented class with a
valid signature
@param name Valid remote class name
@param sig Valid signature
@results Returns NULL
@note This case's results are because find_instantiation_func
doesn't actually load anything in order to do its work.
*/
void TFindInstantiationFuncTester::Case10M()
{
BMessage Archive;
Archive.AddString("class", gRemoteClassName);
Archive.AddString("add_on", gRemoteSig);
instantiation_func f = find_instantiation_func(&Archive);
CPPUNIT_ASSERT(f == NULL);
}
//------------------------------------------------------------------------------
CppUnit::Test* TFindInstantiationFuncTester::Suite()
{
CppUnit::TestSuite* SuiteOfTests = new CppUnit::TestSuite;
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case1);
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case2);
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case3);
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case4);
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case5);
// ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case6);
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case7);
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case8);
// ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case9);
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case10);
// BMessage using versions
#if !defined(TEST_R5)
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case1M);
#endif
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case2M);
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case3M);
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case4M);
// ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case5M);
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case6M);
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case7M);
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case8M);
// ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case9M);
ADD_TEST(SuiteOfTests, TFindInstantiationFuncTester, Case10M);
return SuiteOfTests;
}
//------------------------------------------------------------------------------
/*
* $Log $
*
* $Id $
*
*/
@@ -1,62 +0,0 @@
//------------------------------------------------------------------------------
// FindInstatiationFuncTester.h
//
//------------------------------------------------------------------------------
#ifndef FINDINSTATIATIONFUNCTESTER_H
#define FINDINSTATIATIONFUNCTESTER_H
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
#include "LocalCommon.h"
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
class TFindInstantiationFuncTester : public BTestCase
{
public:
TFindInstantiationFuncTester(std::string name = "") : BTestCase(name) {;}
void Case1();
void Case2();
void Case3();
void Case4();
void Case5();
void Case6();
void Case7();
void Case8();
void Case9();
void Case10();
// BMessage using versions
void Case1M();
void Case2M();
void Case3M();
void Case4M();
void Case5M();
void Case6M();
void Case7M();
void Case8M();
void Case9M();
void Case10M();
static CppUnit::Test* Suite();
};
#endif //FINDINSTATIATIONFUNCTESTER_H
/*
* $Log $
*
* $Id $
*
*/
@@ -1,594 +0,0 @@
//------------------------------------------------------------------------------
// InstantiateObjectTester.cpp
//
/**
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"
// Standard Includes -----------------------------------------------------------
#include <errno.h>
#include <stdexcept>
#include <iostream>
// System Includes -------------------------------------------------------------
#include <Roster.h>
#include <Entry.h>
#include <Path.h>
// Project Includes ------------------------------------------------------------
#include <cppunit/Exception.h>
#include <TestShell.h>
// Local Includes --------------------------------------------------------------
#include "remoteobjectdef/RemoteTestObject.h"
#include "LocalTestObject.h"
using namespace std;
// Local Defines ---------------------------------------------------------------
#define FORMAT_AND_THROW(MSG, ERR) \
FormatAndThrow(__LINE__, __FILE__, MSG, ERR)
// Globals ---------------------------------------------------------------------
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);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Invalid class name tests
//------------------------------------------------------------------------------
/**
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);
// The system implementation returns the image_id of the last addon searched
// Implies the addon is not unloaded. How to verify this behaviour? Should
// the addon be unloaded if it doesn't contain our function? Addons do,
// after all, eat into our allowable memory.
// Verified that addon is *not* unloaded in the Be implementation. If Case8
// runs after this case without explicitely unloaded the addon here, it
// fails because it depends on the addon image not being available within
// the team.
CPPUNIT_ASSERT(id > 0);
unload_add_on(id);
CPPUNIT_ASSERT(errno == B_BAD_VALUE);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Valid class name tests
//------------------------------------------------------------------------------
/**
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.
*/
// No sig
// Local app -- local class
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;
// SuiteOfTests->addTest(
// new CppUnit::TestCaller<TInstantiateObjectTester>("BArchivable::instantiate_object() Test",
// &TInstantiateObjectTester::RunTests));
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, Case12);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case13);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case14);
return SuiteOfTests;
}
//------------------------------------------------------------------------------
void TInstantiateObjectTester::LoadAddon()
{
if (fAddonId > 0)
return;
// We're not testing the roster, so I'm going to just
// find the add-on manually.
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;
// Get the team_id of this app
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);
}
// Get the app_info via the team_id
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;
// It seems that this call to GetRunningAppInfo() is not working because we
// don't have an instance of BApplication somewhere -- the roster, therefore,
// doesn't know about us.
err = Roster.GetRunningAppInfo(team, &ai);
if (err)
{
FORMAT_AND_THROW(" failed to get app_info: ", err);
}
// Return the signature from the app_info
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 $
*
*/
@@ -1,42 +0,0 @@
#ifndef INSTANTIATE_OBJECT_TESTER_H
#define INSTANTIATE_OBJECT_TESTER_H
#include "LocalCommon.h"
class TInstantiateObjectTester : public BTestCase {
public:
TInstantiateObjectTester(
std::string name = "");
void Case1();
void Case2();
void Case3();
void Case4();
void Case5();
void Case6();
void Case7();
void Case8();
void Case9();
void Case10();
void Case11();
void Case12();
void Case13();
void Case14();
void RunTests();
static CppUnit::Test* Suite();
private:
void LoadAddon();
void UnloadAddon();
std::string GetLocalSignature();
private:
image_id fAddonId;
};
#endif // INSTANTIATE_OBJECT_TESTER_H
@@ -1,3 +0,0 @@
SubDir HAIKU_TOP src tests kits support barchivable ;
SubInclude HAIKU_TOP src tests kits support barchivable remoteobjectdef ;
@@ -1,44 +0,0 @@
//------------------------------------------------------------------------------
// LocalCommon.h
//
//------------------------------------------------------------------------------
#ifndef LOCALCOMMON_H
#define LOCALCOMMON_H
// Standard Includes -----------------------------------------------------------
#include <string>
// System Includes -------------------------------------------------------------
#include <Archivable.h>
// Project Includes ------------------------------------------------------------
#include <TestCase.h>
#include <TestUtils.h>
// Local Includes --------------------------------------------------------------
#include "common.h"
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
extern const char* gInvalidClassName;
extern const char* gInvalidSig;
extern const char* gLocalClassName;
extern const char* gLocalSig;
extern const char* gRemoteClassName;
extern const char* gRemoteSig;
extern const char* gValidSig;
#endif //LOCALCOMMON_H
/*
* $Log $
*
* $Id $
*
*/
@@ -1,58 +0,0 @@
//------------------------------------------------------------------------------
// LocalTestObject.cpp
//
//------------------------------------------------------------------------------
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
#include "LocalTestObject.h"
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
//------------------------------------------------------------------------------
TIOTest::TIOTest(int32 i)
: data(i)
{
;
}
//------------------------------------------------------------------------------
TIOTest::TIOTest(BMessage *archive)
{
data = archive->FindInt32("TIOTest::data");
}
//------------------------------------------------------------------------------
status_t TIOTest::Archive(BMessage *archive, bool deep)
{
status_t err = archive->AddString("class", "TIOTest");
if (!err)
err = archive->AddInt32("TIOTest::data", data);
return err;
}
//------------------------------------------------------------------------------
TIOTest* TIOTest::Instantiate(BMessage *archive)
{
if (validate_instantiation(archive, "TIOTest"))
return new TIOTest(archive);
return NULL;
}
//------------------------------------------------------------------------------
/*
* $Log $
*
* $Id $
*
*/
@@ -1,47 +0,0 @@
//------------------------------------------------------------------------------
// LocalTestObject.h
//
//------------------------------------------------------------------------------
#ifndef LOCALTESTOBJECT_H
#define LOCALTESTOBJECT_H
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
#include <Message.h>
#include <Archivable.h>
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
class TIOTest : public BArchivable
{
public:
TIOTest(int32 i);
int32 GetData() { return data; }
// All the archiving-related stuff
TIOTest(BMessage* archive);
status_t Archive(BMessage* archive, bool deep = true);
static TIOTest* Instantiate(BMessage* archive);
private:
int32 data;
};
#endif //LOCALTESTOBJECT_H
/*
* $Log $
*
* $Id $
*
*/
@@ -1,160 +0,0 @@
//------------------------------------------------------------------------------
// ValidateInstantiationTester.cpp
//
/**
Testing for validate_instantiation(BMessage* archive, const char* className)
@note The AllParamsInvalid() and ArchiveInvalid() test are not to be run
against the original implementation, as it does not validate the
archive parameter with a resulting segment violation.
*/
//------------------------------------------------------------------------------
// Standard Includes -----------------------------------------------------------
#include <errno.h>
// System Includes -------------------------------------------------------------
#include <Message.h>
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
#include "ValidateInstantiationTester.h"
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
const char* gClassName = "FooBar";
const char* gBogusClassName = "BarFoo";
//------------------------------------------------------------------------------
/**
validate_instantiation(BMessage* archive, const char* className)
@case All parameters invalid (i.e., NULL)
@param archive NULL
@param className NULL
@results Returns false.
errno is set to B_BAD_VALUE.
*/
void TValidateInstantiationTest::AllParamsInvalid()
{
errno = B_OK;
CPPUNIT_ASSERT(!validate_instantiation(NULL, NULL));
CPPUNIT_ASSERT(errno == B_BAD_VALUE);
}
//------------------------------------------------------------------------------
/**
validate_instantiation(BMessage* archive, const char* className)
@case Valid archive, invalid className (i.e., NULL)
@param archive Valid BMessage pointer
@param className NULL
@results Returns false.
errno is set to B_MISMATCHED_VALUES.
*/
void TValidateInstantiationTest::ClassNameParamInvalid()
{
errno = B_OK;
BMessage Archive;
CPPUNIT_ASSERT(!validate_instantiation(&Archive, NULL));
CPPUNIT_ASSERT(errno == B_MISMATCHED_VALUES);
}
//------------------------------------------------------------------------------
/**
validate_instantiation(BMessage* archive, const char* className)
@case Invalid archive (i.e., NULL), valid className
@param archive NULL
@param className A valid C-string
@results Returns false.
errno is set to B_BAD_VALUE.
@note Do not run this test against the original implementation
as it does not verify the validity of archive, resulting
in a segment violation.
*/
void TValidateInstantiationTest::ArchiveParamInvalid()
{
errno = B_OK;
CPPUNIT_ASSERT(!validate_instantiation(NULL, gClassName));
CPPUNIT_ASSERT(errno == B_BAD_VALUE);
}
//------------------------------------------------------------------------------
/**
validate_instantiation(BMessage* archive, const char* className)
@case Valid archive and className with no string field "class"
in archive
@param archive Valid BMessage pointer
@param className Valid C-string
@results Returns false.
errno is set to B_MISMATCHED_VALUES.
*/
void TValidateInstantiationTest::ClassFieldEmpty()
{
errno = B_OK;
BMessage Archive;
CPPUNIT_ASSERT(!validate_instantiation(&Archive, gClassName));
CPPUNIT_ASSERT(errno == B_MISMATCHED_VALUES);
}
//------------------------------------------------------------------------------
/**
validate_instantiation(BMessage* archive, const char* className)
@case Valid archive with string field "class"; className does
not match the content of "class"
@param archive Valid BMessage pointer with string field "class"
@param className Valid C-string which does not match archive field
"class"
@results Returns false.
errno is set to B_MISMATCHED_VALUES.
*/
void TValidateInstantiationTest::ClassFieldBogus()
{
errno = B_OK;
BMessage Archive;
Archive.AddString("class", gClassName);
CPPUNIT_ASSERT(!validate_instantiation(&Archive, gBogusClassName));
CPPUNIT_ASSERT(errno == B_MISMATCHED_VALUES);
}
//------------------------------------------------------------------------------
/**
validate_instantiation(BMessage* archive, const char* className)
@case All parameters valid
@param archive Valid BMessage pointer with string field "class"
containing a class name
@param className Valid C-string which matches contents of archive field
"class"
@results Returns true.
errno is set to B_OK.
*/
void TValidateInstantiationTest::AllValid()
{
errno = B_OK;
BMessage Archive;
Archive.AddString("class", gClassName);
CPPUNIT_ASSERT(validate_instantiation(&Archive, gClassName));
CPPUNIT_ASSERT(errno == B_OK);
}
//------------------------------------------------------------------------------
CppUnit::Test* TValidateInstantiationTest::Suite()
{
CppUnit::TestSuite* SuiteOfTests = new CppUnit::TestSuite;
#if !defined(TEST_R5)
ADD_TEST(SuiteOfTests, TValidateInstantiationTest, AllParamsInvalid);
#endif
ADD_TEST(SuiteOfTests, TValidateInstantiationTest, ClassNameParamInvalid);
#if !defined(TEST_R5)
ADD_TEST(SuiteOfTests, TValidateInstantiationTest, ArchiveParamInvalid);
#endif
ADD_TEST(SuiteOfTests, TValidateInstantiationTest, ClassFieldEmpty);
ADD_TEST(SuiteOfTests, TValidateInstantiationTest, ClassFieldBogus);
ADD_TEST(SuiteOfTests, TValidateInstantiationTest, AllValid);
return SuiteOfTests;
}
//------------------------------------------------------------------------------
/*
* $Log $
*
* $Id $
*
*/
@@ -1,49 +0,0 @@
//------------------------------------------------------------------------------
// ValidateInstantiationTester.h
//
//------------------------------------------------------------------------------
#ifndef VALIDATEINSTANTIATIONTESTER_H
#define VALIDATEINSTANTIATIONTESTER_H
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
// Project Includes ------------------------------------------------------------
#include "LocalCommon.h"
// Local Includes --------------------------------------------------------------
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
//------------------------------------------------------------------------------
class TValidateInstantiationTest : public BTestCase
{
public:
TValidateInstantiationTest(std::string name = "") : BTestCase(name) {;}
void AllParamsInvalid();
void ClassNameParamInvalid();
void ArchiveParamInvalid();
void ClassFieldEmpty();
void ClassFieldBogus();
void AllValid();
static CppUnit::Test* Suite();
};
//------------------------------------------------------------------------------
#endif //VALIDATEINSTANTIATIONTESTER_H
/*
* $Log $
*
* $Id $
*
*/
@@ -1,52 +0,0 @@
//------------------------------------------------------------------------------
#ifndef COMMON_H
#define COMMON_H
// Standard Includes -----------------------------------------------------------
#include <posix/string.h>
#include <errno.h>
// System Includes -------------------------------------------------------------
// Project Includes ------------------------------------------------------------
#include "cppunit/TestCaller.h"
#include "TestCase.h"
//#include "TestResult.h"
#include "cppunit/TestSuite.h"
// Local Includes --------------------------------------------------------------
// Local Defines ---------------------------------------------------------------
#define assert_err(condition) \
(this->assertImplementation ((condition), std::string((#condition)) + \
strerror(condition),\
__LINE__, __FILE__))
#define ADD_TEST(suitename, classname, funcname) \
(suitename)->addTest(new CppUnit::TestCaller<classname>(std::string("BArchivable::") + \
std::string((#funcname)), &classname::funcname));
#define ADD_TEST4(classbeingtested, suitename, classname, funcname) \
(suitename)->addTest(new TestCaller<classname>((#classbeingtested "::" #funcname), \
&classname::funcname));
#define CHECK_ERRNO \
cout << endl << "errno == \"" << strerror(errno) << "\" (" << errno \
<< ") in " << __PRETTY_FUNCTION__ << endl
#define CHECK_STATUS(status__) \
cout << endl << "status_t == \"" << strerror((status__)) << "\" (" \
<< (status__) << ") in " << __PRETTY_FUNCTION__ << endl
// Globals ---------------------------------------------------------------------
#endif //COMMON_H
/*
* $Log $
*
* $Id $
*
*/
@@ -1,61 +0,0 @@
//------------------------------------------------------------------------------
// main.cpp
//
//------------------------------------------------------------------------------
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
#include "LocalCommon.h"
#include "BArchivableTester.h"
#include "ValidateInstantiationTester.h"
#include "InstantiateObjectTester.h"
#include "FindInstantiationFuncTester.h"
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
//------------------------------------------------------------------------------
// Function: addonTestFunc()
// Descr: This function is called by the test application to
// get a pointer to the test to run.
//------------------------------------------------------------------------------
Test* addonTestFunc()
{
TestSuite* tests = new TestSuite("BArchivable");
tests->addTest(TBArchivableTestCase::Suite());
tests->addTest(TValidateInstantiationTest::Suite());
tests->addTest(TInstantiateObjectTester::Suite());
tests->addTest(TFindInstantiationFuncTester::Suite());
return tests;
}
int main()
{
Test* tests = addonTestFunc();
TextTestResult Result;
tests->run(&Result);
cout << Result << endl;
delete tests;
return !Result.wasSuccessful();
}
/*
* $Log $
*
* $Id $
*
*/
@@ -1,153 +0,0 @@
/*
$Id: AutolockLockerTest.cpp 332 2002-07-19 06:45:28Z tylerdauwalder $
This file tests all use cases of the BAutolock when used with a BLocker.
BLooper based tests are done seperately.
*/
#include "ThreadedTestCaller.h"
#include "AutolockLockerTest.h"
#include <Autolock.h>
#include <OS.h>
const bigtime_t SNOOZE_TIME = 250000;
/*
* Method: AutolockLockerTest::AutolockLockerTest()
* Descr: This method is the only constructor for the AutolockLockerTest
* class.
*/
AutolockLockerTest::AutolockLockerTest(std::string name) :
BThreadedTestCase(name), theLocker(new BLocker)
{
}
/*
* Method: AutolockLockerTest::~AutolockLockerTest()
* Descr: This method is the destructor for the AutolockLockerTest class.
* It only deallocates the autolocker and locker.
*/
AutolockLockerTest::~AutolockLockerTest()
{
delete theLocker;
theLocker = NULL;
}
/*
* Method: AutolockLockerTest::TestThread1()
* Descr: This method performs the tests on the Autolock. It first acquires the
* lock and sleeps for a short time. It deletes the lock rather than Unlock()
* it in order to test the other two threads. Then, it constructs a new
* Locker and Autolock and checks that both the Autolock and the Locker are
* both locked. Then, the Autolock is released by deleting it. The Locker
* is checked to see that it is now released. This is then repeated for an Autolock
* constructed by passing a reference to the Locker.
*/
void AutolockLockerTest::TestThread1(void)
{
BAutolock *theAutolock;
NextSubTest();
CPPUNIT_ASSERT(theLocker->Lock());
CPPUNIT_ASSERT(theLocker->LockingThread() == find_thread(NULL));
snooze(SNOOZE_TIME);
delete theLocker;
NextSubTest();
theLocker = new BLocker;
theAutolock = new BAutolock(theLocker);
CPPUNIT_ASSERT(theLocker->IsLocked());
CPPUNIT_ASSERT(theLocker->LockingThread() == find_thread(NULL));
CPPUNIT_ASSERT(theAutolock->IsLocked());
NextSubTest();
delete theAutolock;
theAutolock = NULL;
CPPUNIT_ASSERT(theLocker->LockingThread() != find_thread(NULL));
NextSubTest();
theAutolock = new BAutolock(*theLocker);
CPPUNIT_ASSERT(theLocker->IsLocked());
CPPUNIT_ASSERT(theLocker->LockingThread() == find_thread(NULL));
CPPUNIT_ASSERT(theAutolock->IsLocked());
NextSubTest();
delete theAutolock;
theAutolock = NULL;
CPPUNIT_ASSERT(theLocker->LockingThread() != find_thread(NULL));
}
/*
* Method: AutolockLockerTest::TestThread2()
* Descr: This method performs the tests on the Autolock. It first sleeps for a short
* time and then tries to acquire the lock with an Autolock. It passes a pointer
* to the lock to the Autolock. It expects the acquisition to fail and IsLocked()
* is tested to be sure.
*/
void AutolockLockerTest::TestThread2(void)
{
NextSubTest();
snooze(SNOOZE_TIME / 10);
BAutolock theAutolock(theLocker);
CPPUNIT_ASSERT(!theAutolock.IsLocked());
}
/*
* Method: AutolockLockerTest::TestThread3()
* Descr: This method performs the tests on the Autolock. It first sleeps for a short
* time and then tries to acquire the lock with an Autolock. It passes a reference
* to the lock to the Autolock. It expects the acquisition to fail and IsLocked()
* is tested to be sure.
*/
void AutolockLockerTest::TestThread3(void)
{
NextSubTest();
snooze(SNOOZE_TIME / 10);
BAutolock theAutolock(*theLocker);
CPPUNIT_ASSERT(!theAutolock.IsLocked());
}
/*
* Method: AutolockLockerTest::suite()
* Descr: This static member function returns a test caller for performing
* the "AutolockLockerTest" test. The test caller
* is created as a ThreadedTestCaller (typedef'd as
* BenaphoreLockCountTest1Caller) with three independent threads.
*/
CppUnit::Test *AutolockLockerTest::suite(void)
{
typedef BThreadedTestCaller <AutolockLockerTest >
AutolockLockerTestCaller;
AutolockLockerTest *theTest = new AutolockLockerTest("");
AutolockLockerTestCaller *threadedTest = new AutolockLockerTestCaller("BAutolock::Locker Test", theTest);
threadedTest->addThread("A", &AutolockLockerTest::TestThread1);
threadedTest->addThread("B", &AutolockLockerTest::TestThread2);
threadedTest->addThread("C", &AutolockLockerTest::TestThread3);
return(threadedTest);
}
@@ -1,37 +0,0 @@
/*
$Id: AutolockLockerTest.h 332 2002-07-19 06:45:28Z tylerdauwalder $
This file defines the class for performing all BAutolock tests on a
BLocker.
*/
#ifndef AutolockLockerTest_H
#define AutolockLockerTest_H
#include "ThreadedTestCase.h"
#include <string>
class BLocker;
class CppUnit::Test;
class AutolockLockerTest : public BThreadedTestCase {
private:
BLocker *theLocker;
public:
static CppUnit::Test *suite(void);
void TestThread1(void);
void TestThread2(void);
void TestThread3(void);
AutolockLockerTest(std::string);
virtual ~AutolockLockerTest();
};
#endif
@@ -1,96 +0,0 @@
/*
$Id: AutolockLooperTest.cpp 332 2002-07-19 06:45:28Z tylerdauwalder $
This file tests all use cases of the BAutolock when used with a BLooper.
BLocker based tests are done seperately.
*/
#include "ThreadedTestCaller.h"
#include "AutolockLooperTest.h"
#include <Autolock.h>
#include <Looper.h>
#include <OS.h>
const bigtime_t SNOOZE_TIME = 250000;
/*
* Method: AutolockLooperTest::AutolockLooperTest()
* Descr: This method is the only constructor for the AutolockLooperTest
* class.
*/
AutolockLooperTest::AutolockLooperTest(std::string name) :
BThreadedTestCase(name), theLooper(new BLooper)
{
theLooper->Run();
}
/*
* Method: AutolockLooperTest::~AutolockLooperTest()
* Descr: This method is the destructor for the AutolockLooperTest class.
* It only deallocates the autoLooper and Looper.
*/
AutolockLooperTest::~AutolockLooperTest()
{
if (theLooper != NULL)
theLooper->Lock();
theLooper->Quit();
}
/*
* Method: AutolockLooperTest::TestThread1()
* Descr: This method performs the tests on the Autolock. It constructs a new
* Autolock and checks that both the Autolock and the Looper are
* both locked. Then, the Autolock is released by deleting it. The Looper
* is checked to see that it is now released.
*/
void AutolockLooperTest::TestThread1(void)
{
BAutolock *theAutolock = new BAutolock(theLooper);
NextSubTest();
CPPUNIT_ASSERT(theLooper->IsLocked());
CPPUNIT_ASSERT(theLooper->LockingThread() == find_thread(NULL));
CPPUNIT_ASSERT(theAutolock->IsLocked());
NextSubTest();
delete theAutolock;
theAutolock = NULL;
CPPUNIT_ASSERT(theLooper->LockingThread() != find_thread(NULL));
}
/*
* Method: AutolockLooperTest::suite()
* Descr: This static member function returns a test caller for performing
* the "AutolockLooperTest" test. The test caller
* is created as a ThreadedTestCaller (typedef'd as
* BenaphoreLockCountTest1Caller) with three independent threads.
*/
CppUnit::Test *AutolockLooperTest::suite(void)
{
typedef BThreadedTestCaller <AutolockLooperTest >
AutolockLooperTestCaller;
AutolockLooperTest *theTest = new AutolockLooperTest("");
AutolockLooperTestCaller *threadedTest = new AutolockLooperTestCaller("BAutolock::Looper Test", theTest);
threadedTest->addThread("A", &AutolockLooperTest::TestThread1);
return(threadedTest);
}
@@ -1,36 +0,0 @@
/*
$Id: AutolockLooperTest.h 332 2002-07-19 06:45:28Z tylerdauwalder $
This file defines the class for performing all BAutolock tests on a
BLooper.
*/
#ifndef AutolockLooperTest_H
#define AutolockLooperTest_H
#include "ThreadedTestCase.h"
#include <string>
class BLooper;
class CppUnit::Test;
class AutolockLooperTest : public BThreadedTestCase {
private:
BLooper *theLooper;
public:
static Test *suite(void);
void TestThread1(void);
AutolockLooperTest(std::string);
virtual ~AutolockLooperTest();
};
#endif
@@ -1,19 +0,0 @@
/*
$Id:
*/
#include "AutolockLockerTest.h"
#include "AutolockLooperTest.h"
#include "cppunit/Test.h"
#include "cppunit/TestSuite.h"
CppUnit::Test* AutolockTestSuite()
{
CppUnit::TestSuite *testSuite = new CppUnit::TestSuite();
testSuite->addTest(AutolockLockerTest::suite());
testSuite->addTest(AutolockLooperTest::suite());
return testSuite;
}
@@ -1,8 +0,0 @@
#ifndef _autolock_test_h_
#define _autolock_test_h_
class CppUnit::Test;
CppUnit::Test* AutolockTestSuite();
#endif // _autolock_test_h_
@@ -1,42 +0,0 @@
/*
$Id: AutolockTestAddon.cpp 10 2002-07-09 12:24:59Z ejakowatz $
This file declares the addonTestName string and addonTestFunc
function for the BLocker tests. These symbols will be used
when the addon is loaded.
*/
#include "AutolockLockerTest.h"
#include "AutolockLooperTest.h"
#include <Autolock.h>
#include "Autolock.h"
#include "TestAddon.h"
#include "TestSuite.h"
/*
* Function: addonTestFunc()
* Descr: This function is called by the test application to
* get a pointer to the test to run. The BLocker test
* is a test suite. A series of tests are added to
* the suite. Each test appears twice, once for
* the Be implementation of BLocker, once for the
* Haiku implementation.
*/
Test *addonTestFunc(void)
{
TestSuite *testSuite = new TestSuite("BAutolock");
testSuite->addTest(AutolockLockerTest<BAutolock, BLocker>::suite());
testSuite->addTest(AutolockLooperTest<BAutolock, BLooper>::suite());
testSuite->addTest(
AutolockLockerTest<OpenBeOS::BAutolock, OpenBeOS::BLocker>::suite());
testSuite->addTest(
AutolockLooperTest<OpenBeOS::BAutolock, BLooper>::suite());
return(testSuite);
}
@@ -1,50 +0,0 @@
/*
$Id: BlockCacheConcurrencyTest.h 4522 2003-09-07 11:53:03Z bonefish $
This file defines a class for testing BBlockCache
*/
#ifndef BlockCacheConcurrencyTest_H
#define BlockCacheConcurrencyTest_H
#include "ThreadedTestCase.h"
#include <string>
#include <OS.h>
class BBlockCache;
class BList;
class BlockCacheConcurrencyTest : public BThreadedTestCase {
private:
BBlockCache *theObjCache;
BBlockCache *theMallocCache;
int numBlocksInCache;
size_t sizeOfBlocksInCache;
size_t sizeOfNonCacheBlocks;
void *GetBlock(BBlockCache *theCache, size_t blockSize,
thread_id theThread, BList *cacheList, BList *nonCacheList);
void SaveBlock(BBlockCache *theCache, void *, size_t blockSize,
thread_id theThread, BList *cacheList, BList *nonCacheList);
void FreeBlock(void *, size_t blockSize, bool isMallocTest,
thread_id theThread, BList *cacheList,
BList *nonCacheList);
void TestBlockCache(BBlockCache *theCache, bool isMallocTest);
public:
static Test *suite(void);
void TestThreadObj(void);
void TestThreadMalloc(void);
virtual void setUp(void);
virtual void tearDown(void);
BlockCacheConcurrencyTest(std::string);
virtual ~BlockCacheConcurrencyTest();
};
#endif
@@ -1,49 +0,0 @@
/*
$Id: BlockCacheExerciseTest.h 4522 2003-09-07 11:53:03Z bonefish $
This file defines a class for performing tests on the BBlockCache class.
*/
#ifndef BlockCacheExerciseTest_H
#define BlockCacheExerciseTest_H
#include "cppunit/TestCase.h"
#include <List.h>
class BBlockCache;
class BlockCacheExerciseTest : public CppUnit::TestCase {
private:
BBlockCache *theCache;
int numBlocksInCache;
size_t sizeOfBlocksInCache;
size_t sizeOfNonCacheBlocks;
bool isMallocTest;
BList freeList;
BList usedList;
BList nonCacheList;
void BuildLists(void);
void *GetBlock(size_t blockSize);
void SaveBlock(void *, size_t blockSize);
void FreeBlock(void *, size_t blockSize);
void TestBlockCache(void);
protected:
public:
static CppUnit::Test *suite(void);
BlockCacheExerciseTest(std::string = "");
virtual ~BlockCacheExerciseTest();
virtual void PerformTest(void);
};
#endif
@@ -1,21 +0,0 @@
/*
$Id: BlockCacheTest.cpp 4522 2003-09-07 11:53:03Z bonefish $
*/
#include "cppunit/Test.h"
#include "cppunit/TestSuite.h"
#include "BlockCacheExerciseTest.h"
#include "BlockCacheConcurrencyTest.h"
CppUnit::Test* BlockCacheTestSuite()
{
CppUnit::TestSuite *testSuite = new CppUnit::TestSuite();
testSuite->addTest(BlockCacheExerciseTest::suite());
testSuite->addTest(BlockCacheConcurrencyTest::suite());
return testSuite;
}
@@ -1,8 +0,0 @@
#ifndef _blockcache_test_h_
#define _blockcache_test_h_
class CppUnit::Test;
CppUnit::Test* BlockCacheTestSuite();
#endif // _blockcache_test_h_
@@ -1,215 +0,0 @@
/*
$Id: BenaphoreLockCountTest1.cpp 301 2002-07-18 05:32:00Z tylerdauwalder $
This file implements a test class for testing BLocker functionality.
It tests use cases "Count Lock Requests" for a benaphore style BLocker.
The test works by:
- checking the lock requests
- acquiring the lock
- checking the lock requests
- staring a thread which times out acquiring the lock and then blocks
again waiting for the lock
- checking the lock requests
- start a second thread which times out acquiring the lock and then blocks
again waiting for the lock
- checking the lock requests
- release the lock
- each blocked thread acquires the lock, checks the lock requests and releases
the lock before terminating
- the main thread checks the lock requests one last time
*/
#include "BenaphoreLockCountTest1.h"
#include <cppunit/Test.h>
#include <cppunit/TestSuite.h>
#include <Locker.h>
#include <ThreadedTestCaller.h>
// This constant is used to determine the number of microseconds to
// sleep during major steps of the test.
const bigtime_t SNOOZE_TIME = 100000;
/*
* Method: BenaphoreLockCountTest1::BenaphoreLockCountTest1()
* Descr: This is the constructor for this test class.
*/
BenaphoreLockCountTest1::BenaphoreLockCountTest1(std::string name) :
LockerTestCase(name, true)
{
}
/*
* Method: BenaphoreLockCountTest1::~BenaphoreLockTestCountTest1()
* Descr: This is the destructor for this test class.
*/
BenaphoreLockCountTest1::~BenaphoreLockCountTest1()
{
}
/*
* Method: BenaphoreLockCountTest1::CheckLockRequests()
* Descr: This member function checks the actual number of lock requests
* that the BLocker thinks are outstanding versus the number
* passed in. If they match, true is returned.
*/
bool BenaphoreLockCountTest1::CheckLockRequests(int expected)
{
int actual = theLocker->CountLockRequests();
return(actual == expected);
}
/*
* Method: BenaphoreLockCountTest1::TestThread1()
* Descr: This member function performs the main portion of the test.
* It first acquires thread2Lock and thread3Lock. This ensures
* that thread2 and thread3 will block until this thread wants
* them to start running. It then checks the lock count, acquires
* the lock and checks the lock count again. It unlocks each
* of the other two threads in turn and rechecks the lock count.
* Finally, it releases the lock and sleeps for a short while
* for the other two threads to finish. At the end, it checks
* the lock count on final time.
*/
void BenaphoreLockCountTest1::TestThread1(void)
{
SafetyLock theSafetyLock1(theLocker);
SafetyLock theSafetyLock2(&thread2Lock);
SafetyLock theSafetyLock3(&thread3Lock);
CPPUNIT_ASSERT(thread2Lock.Lock());
NextSubTest();
CPPUNIT_ASSERT(thread3Lock.Lock());
NextSubTest();
CPPUNIT_ASSERT(CheckLockRequests(0));
NextSubTest();
CPPUNIT_ASSERT(theLocker->Lock());
NextSubTest();
CPPUNIT_ASSERT(CheckLockRequests(1));
NextSubTest();
thread2Lock.Unlock();
NextSubTest();
snooze(SNOOZE_TIME);
NextSubTest();
CPPUNIT_ASSERT(CheckLockRequests(3));
NextSubTest();
thread3Lock.Unlock();
NextSubTest();
snooze(SNOOZE_TIME);
NextSubTest();
CPPUNIT_ASSERT(CheckLockRequests(5));
NextSubTest();
theLocker->Unlock();
NextSubTest();
snooze(SNOOZE_TIME);
NextSubTest();
CPPUNIT_ASSERT(CheckLockRequests(2));
NextSubTest();
}
/*
* Method: BenaphoreLockCountTest1::TestThread2()
* Descr: This member function defines the actions of the second thread of
* the test. First it sleeps for a short while and then blocks on
* the thread2Lock. When the first thread releases it, this thread
* begins its testing. It times out attempting to acquire the main
* lock and then blocks to acquire the lock. Once that lock is
* acquired, the lock count is checked before finishing this thread.
*/
void BenaphoreLockCountTest1::TestThread2(void)
{
SafetyLock theSafetyLock1(theLocker);
snooze(SNOOZE_TIME / 10);
NextSubTest();
CPPUNIT_ASSERT(thread2Lock.Lock());
NextSubTest();
CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT);
NextSubTest();
CPPUNIT_ASSERT(theLocker->Lock());
NextSubTest();
int actual = theLocker->CountLockRequests();
NextSubTest();
CPPUNIT_ASSERT((actual == 3) || (actual == 4));
NextSubTest();
theLocker->Unlock();
NextSubTest();
}
/*
* Method: BenaphoreLockCountTest1::TestThread3()
* Descr: This member function defines the actions of the second thread of
* the test. First it sleeps for a short while and then blocks on
* the thread3Lock. When the first thread releases it, this thread
* begins its testing. It times out attempting to acquire the main
* lock and then blocks to acquire the lock. Once that lock is
* acquired, the lock count is checked before finishing this thread.
*/
void BenaphoreLockCountTest1::TestThread3(void)
{
SafetyLock theSafetyLock1(theLocker);
snooze(SNOOZE_TIME / 10);
NextSubTest();
CPPUNIT_ASSERT(thread3Lock.Lock());
NextSubTest();
CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT);
NextSubTest();
CPPUNIT_ASSERT(theLocker->Lock());
NextSubTest();
int actual = theLocker->CountLockRequests();
NextSubTest();
CPPUNIT_ASSERT((actual == 3) || (actual == 4));
NextSubTest();
theLocker->Unlock();
NextSubTest();
}
/*
* Method: BenaphoreLockCountTest1::suite()
* Descr: This static member function returns a test caller for performing
* the "BenaphoreLockCountTest1" test. The test caller
* is created as a ThreadedTestCaller (typedef'd as
* BenaphoreLockCountTest1Caller) with three independent threads.
*/
CppUnit::Test *BenaphoreLockCountTest1::suite(void)
{
BenaphoreLockCountTest1 *theTest = new BenaphoreLockCountTest1("");
BThreadedTestCaller<BenaphoreLockCountTest1> *threadedTest =
new BThreadedTestCaller<BenaphoreLockCountTest1>("BLocker::Benaphore Lock Count Test #1", theTest);
threadedTest->addThread("A", &BenaphoreLockCountTest1::TestThread1);
threadedTest->addThread("B", &BenaphoreLockCountTest1::TestThread2);
threadedTest->addThread("C", &BenaphoreLockCountTest1::TestThread3);
return(threadedTest);
}
@@ -1,40 +0,0 @@
/*
$Id: BenaphoreLockCountTest1.h 301 2002-07-18 05:32:00Z tylerdauwalder $
This file defines a classes for performing one test of BLocker
functionality.
*/
#ifndef BenaphoreLockCountTest1_H
#define BenaphoreLockCountTest1_H
#include <string>
#include "LockerTestCase.h"
class BenaphoreLockCountTest1 : public LockerTestCase {
private:
BLocker thread2Lock;
BLocker thread3Lock;
bool CheckLockRequests(int);
protected:
public:
void TestThread1(void);
void TestThread2(void);
void TestThread3(void);
BenaphoreLockCountTest1(std::string);
virtual ~BenaphoreLockCountTest1();
static CppUnit::Test *suite(void);
};
#endif
@@ -1,190 +0,0 @@
/*
$Id: ConcurrencyTest1.cpp 301 2002-07-18 05:32:00Z tylerdauwalder $
This file implements a test class for testing BLocker functionality.
It tests use cases "Locking 1", "Locking 2", "Unlocking", "Is Locked",
"Locking Thread" and "Count Locks".
*/
#include <ThreadedTestCaller.h>
#include "ConcurrencyTest1.h"
#include <cppunit/TestSuite.h>
#include <Locker.h>
// This constant indicates the number of times the thread should test the
// acquisition and release of the BLocker.
const int32 MAXLOOP = 10000;
/*
* Method: ConcurrencyTest1::ConcurrencyTest1()
* Descr: This is the only constructor for this test case. It takes a
* test name and a flag to indicate whether to test a benaphore
* or semaphore type BLocker.
*/
ConcurrencyTest1::ConcurrencyTest1(std::string name, bool benaphoreFlag) :
LockerTestCase(name, benaphoreFlag), lockTestValue(false)
{
}
/*
* Method: ConcurrencyTest1::~ConcurrencyTest1()
* Descr: This is the descriptor for this test case.
*/
ConcurrencyTest1::~ConcurrencyTest1()
{
}
/*
* Method: ConcurrencyTest1::setUp()
* Descr: This member is called before starting the actual test threads
* and is used to ensure that the class is initialized for the
* testing. It just sets the "lockTestValue" flag to false. This
* flag is used to show that there is mutual exclusion between the
* threads.
*/
void
ConcurrencyTest1::setUp(void)
{
lockTestValue = false;
}
/*
* Method: ConcurrencyTest1::suite()
* Descr: This static member function returns a test suite for performing
* all combinations of "ConcurrencyTest1". The test suite contains
* two instances of the test. One is performed on a benaphore,
* the other on a semaphore based BLocker. Each individual test
* is created as a ThreadedTestCase (typedef'd as
* ConcurrencyTest1Caller) with three independent threads.
*/
CppUnit::Test *ConcurrencyTest1::suite(void)
{
typedef BThreadedTestCaller<ConcurrencyTest1>
ConcurrencyTest1Caller;
CppUnit::TestSuite *testSuite = new CppUnit::TestSuite("ConcurrencyTest1");
// Make a benaphore based test object, create a ThreadedTestCase for it and add
// three threads to it.
ConcurrencyTest1 *theTest = new ConcurrencyTest1("Benaphore", true);
ConcurrencyTest1Caller *threadedTest1 = new ConcurrencyTest1Caller("BLocker::Concurrency Test #1 (benaphore)", theTest);
threadedTest1->addThread("A", &ConcurrencyTest1::TestThread);
threadedTest1->addThread("B", &ConcurrencyTest1::TestThread);
threadedTest1->addThread("C", &ConcurrencyTest1::TestThread);
// Make a semaphore based test object, create a ThreadedTestCase for it and add
// three threads to it.
theTest = new ConcurrencyTest1("Semaphore", false);
ConcurrencyTest1Caller *threadedTest2 = new ConcurrencyTest1Caller("BLocker::Concurrency Test #1 (semaphore)", theTest);
threadedTest2->addThread("A", &ConcurrencyTest1::TestThread);
threadedTest2->addThread("B", &ConcurrencyTest1::TestThread);
threadedTest2->addThread("C", &ConcurrencyTest1::TestThread);
testSuite->addTest(threadedTest1);
testSuite->addTest(threadedTest2);
return(testSuite);
}
/*
* Method: ConcurrencyTest1::AcquireLock()
* Descr: This member function is passed the number of times through the
* acquisition loop (lockAttempt) and whether or not this is
* the first acquisition of the lock within this iteration.
* Based on these values, it may do a LockWithTimeout() or just
* a plain Lock() on theLocker. This is done to get coverage of
* both lock acquisition methods on the BLocker.
*/
bool ConcurrencyTest1::AcquireLock(int lockAttempt,
bool firstAcquisition)
{
bool timeoutLock;
bool result;
if (firstAcquisition) {
timeoutLock = ((lockAttempt % 2) == 1);
} else {
timeoutLock = (((lockAttempt / 2) % 2) == 1);
}
if (timeoutLock) {
result = (theLocker->LockWithTimeout(1000000) == B_OK);
} else {
result = theLocker->Lock();
}
return(result);
}
/*
* Method: ConcurrencyTest1::TestThread()
* Descr: This method is the core of the test. Each of the three threads
* run this method to perform the concurrency test. First, the
* SafetyLock class (see LockerTestCase.h) is used to make sure that
* the lock is released if an assertion happens. Then, each thread
* iterates MAXLOOP times through the main loop where the following
* actions are performed:
* - CheckLock() is used to show that the thread does not have
* the lock.
* - The thread acquires the lock.
* - The thread confirms that mutual exclusion is OK by testing
* lockTestValue.
* - The thread confirms the lock is held once by the thread.
* - The thread acquires the lock again.
* - The thread confirms the lock is held twice now by the thread.
* - The thread releases the lock once.
* - The thread confirms the lock is held once now.
* - The thread confirms that mutual exclusion is still OK by
* testing lockTestValue.
* - The thread releases the lock again.
* - The thread confirms that the lock is no longer held.
*/
void ConcurrencyTest1::TestThread(void)
{
int i;
SafetyLock theSafetyLock(theLocker);
for (i = 0; i < MAXLOOP; i++) {
// Print out 10 sub test markers per thread
if (i % (MAXLOOP / 10) == 0)
NextSubTest();
CheckLock(0);
CPPUNIT_ASSERT(AcquireLock(i, true));
CPPUNIT_ASSERT(!lockTestValue);
lockTestValue = true;
CheckLock(1);
CPPUNIT_ASSERT(AcquireLock(i, false));
CheckLock(2);
theLocker->Unlock();
CheckLock(1);
CPPUNIT_ASSERT(lockTestValue);
lockTestValue = false;
theLocker->Unlock();
CheckLock(0);
}
}
@@ -1,36 +0,0 @@
/*
$Id: ConcurrencyTest1.h 301 2002-07-18 05:32:00Z tylerdauwalder $
This file defines a class for performing one test of BLocker
functionality.
*/
#ifndef ConcurrencyTest1_H
#define ConcurrencyTest1_H
#include "LockerTestCase.h"
class ConcurrencyTest1 :
public LockerTestCase {
private:
bool lockTestValue;
bool AcquireLock(int, bool);
public:
ConcurrencyTest1(std::string, bool);
virtual ~ConcurrencyTest1();
void setUp(void);
void TestThread(void);
static Test *suite(void);
};
#endif
@@ -1,232 +0,0 @@
/*
$Id: ConcurrencyTest2.cpp 301 2002-07-18 05:32:00Z tylerdauwalder $
This file implements a test class for testing BLocker functionality.
It tests use cases "Locking 1", "Locking 2", "Unlocking", "Is Locked",
"Locking Thread" and "Count Locks". It is essentially the same as Test1.cpp
except it makes the first LockWithTimeout inside the threads timeout. The
reason for this is because the implementation of BLocker by Be and with Haiku
is such that after one timeout occurs on a benaphore style BLocker, the lock
effectively becomes a semaphore style BLocker. This test tests that condition.
*/
#include "ThreadedTestCaller.h"
#include "ConcurrencyTest2.h"
#include "cppunit/TestSuite.h"
#include "Locker.h"
// This constant indicates the number of times the thread should test the
// acquisition and release of the BLocker.
const int32 MAXLOOP = 10000;
// This constant is used to determine the number of microseconds to
// sleep during major steps of the test.
const bigtime_t SNOOZE_TIME = 200000;
/*
* Method: ConcurrencyTest2::ConcurrencyTest2()
* Descr: This is the only constructor for this test case. It takes a
* test name and a flag to indicate whether to test a benaphore
* or semaphore type BLocker.
*/
ConcurrencyTest2::ConcurrencyTest2(std::string name, bool benaphoreFlag) :
LockerTestCase(name, benaphoreFlag), lockTestValue(false)
{
}
/*
* Method: ConcurrencyTest2::~ConcurrencyTest2()
* Descr: This is the descriptor for this test case.
*/
ConcurrencyTest2::~ConcurrencyTest2()
{
}
/*
* Method: ConcurrencyTest2::setUp()
* Descr: This member is called before starting the actual test threads
* and is used to ensure that the class is initialized for the
* testing. It just sets the "lockTestValue" flag to false. This
* flag is used to show that there is mutual exclusion between the
* threads.
*/
void
ConcurrencyTest2::setUp(void)
{
lockTestValue = false;
}
/*
* Method: ConcurrencyTest2::suite()
* Descr: This static member function returns a test suite for performing
* all combinations of "ConcurrencyTest2". The test suite contains
* two instances of the test. One is performed on a benaphore,
* the other on a semaphore based BLocker. Each individual test
* is created as a ThreadedTestCase (typedef'd as
* ConcurrencyTest2Caller) with three independent threads.
*/
CppUnit::Test *ConcurrencyTest2::suite(void)
{
typedef BThreadedTestCaller <ConcurrencyTest2 >
ConcurrencyTest2Caller;
CppUnit::TestSuite *testSuite = new CppUnit::TestSuite("ConcurrencyTest2");
// Make a benaphore based test object, create a ThreadedTestCase for it and add
// three threads to it.
ConcurrencyTest2 *theTest = new ConcurrencyTest2("Benaphore", true);
ConcurrencyTest2Caller *threadedTest1 = new ConcurrencyTest2Caller("BLocker::Concurrency Test #2 (benaphore)", theTest);
threadedTest1->addThread("Acquire", &ConcurrencyTest2::AcquireThread);
threadedTest1->addThread("Timeout1", &ConcurrencyTest2::TimeoutThread);
threadedTest1->addThread("Timeout2", &ConcurrencyTest2::TimeoutThread);
// Make a semaphore based test object, create a ThreadedTestCase for it and add
// three threads to it.
theTest = new ConcurrencyTest2("Semaphore", false);
ConcurrencyTest2Caller *threadedTest2 = new ConcurrencyTest2Caller("BLocker::Concurrency Test #2 (semaphore)", theTest);
threadedTest2->addThread("Acquire", &ConcurrencyTest2::AcquireThread);
threadedTest2->addThread("Timeout1", &ConcurrencyTest2::TimeoutThread);
threadedTest2->addThread("Timeout2", &ConcurrencyTest2::TimeoutThread);
testSuite->addTest(threadedTest1);
testSuite->addTest(threadedTest2);
return(testSuite);
}
/*
* Method: ConcurrencyTest2::AcquireThread()
* Descr: This member function acquires the lock, sleeps for SNOOZE_TIME,
* releases the lock and then launches into the lock loop test.
*/
void ConcurrencyTest2::AcquireThread(void)
{
SafetyLock theSafetyLock(theLocker);
CPPUNIT_ASSERT(theLocker->Lock());
NextSubTest();
snooze(SNOOZE_TIME);
NextSubTest();
theLocker->Unlock();
NextSubTest();
LockingLoop();
NextSubTest();
}
/*
* Method: ConcurrencyTest2::AcquireLock()
* Descr: This member function is passed the number of times through the
* acquisition loop (lockAttempt) and whether or not this is
* the first acquisition of the lock within this iteration.
* Based on these values, it may do a LockWithTimeout() or just
* a plain Lock() on theLocker. This is done to get coverage of
* both lock acquisition methods on the BLocker.
*/
bool ConcurrencyTest2::AcquireLock(int lockAttempt,
bool firstAcquisition)
{
bool timeoutLock;
bool result;
if (firstAcquisition) {
timeoutLock = ((lockAttempt % 2) == 1);
} else {
timeoutLock = (((lockAttempt / 2) % 2) == 1);
}
if (timeoutLock) {
result = (theLocker->LockWithTimeout(1000000) == B_OK);
} else {
result = theLocker->Lock();
}
return(result);
}
/*
* Method: ConcurrencyTest2::TimeoutThread()
* Descr: This member function sleeps for a short time and then attempts to
* acquire the lock for SNOOZE_TIME/10 seconds. This acquisition
* should timeout. Then the locking loop is started.
*/
void ConcurrencyTest2::TimeoutThread(void)
{
SafetyLock theSafetyLock(theLocker);
snooze(SNOOZE_TIME/2);
NextSubTest();
CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME/10) == B_TIMED_OUT);
NextSubTest();
LockingLoop();
NextSubTest();
}
/*
* Method: ConcurrencyTest2::TestThread()
* Descr: This method is the core of the test. Each of the three threads
* run this method to perform the concurrency test. First, the
* SafetyLock class (see LockerTestCase.h) is used to make sure that
* the lock is released if an assertion happens. Then, each thread
* iterates MAXLOOP times through the main loop where the following
* actions are performed:
* - CheckLock() is used to show that the thread does not have
* the lock.
* - The thread acquires the lock.
* - The thread confirms that mutual exclusion is OK by testing
* lockTestValue.
* - The thread confirms the lock is held once by the thread.
* - The thread acquires the lock again.
* - The thread confirms the lock is held twice now by the thread.
* - The thread releases the lock once.
* - The thread confirms the lock is held once now.
* - The thread confirms that mutual exclusion is still OK by
* testing lockTestValue.
* - The thread releases the lock again.
* - The thread confirms that the lock is no longer held.
*/
void ConcurrencyTest2::LockingLoop(void)
{
int i;
SafetyLock theSafetyLock(theLocker);
for (i = 0; i < MAXLOOP; i++) {
CheckLock(0);
CPPUNIT_ASSERT(AcquireLock(i, true));
CPPUNIT_ASSERT(!lockTestValue);
lockTestValue = true;
CheckLock(1);
CPPUNIT_ASSERT(AcquireLock(i, false));
CheckLock(2);
theLocker->Unlock();
CheckLock(1);
CPPUNIT_ASSERT(lockTestValue);
lockTestValue = false;
theLocker->Unlock();
CheckLock(0);
}
}
@@ -1,35 +0,0 @@
/*
$Id: ConcurrencyTest2.h 301 2002-07-18 05:32:00Z tylerdauwalder $
This file defines a classes for performing one test of BLocker
functionality.
*/
#ifndef ConcurrencyTest2_H
#define ConcurrencyTest2_H
#include "LockerTestCase.h"
class ConcurrencyTest2 : public LockerTestCase {
private:
bool lockTestValue;
void TestThread(void);
bool AcquireLock(int, bool);
void LockingLoop(void);
public:
ConcurrencyTest2(std::string, bool);
virtual ~ConcurrencyTest2();
void setUp(void);
void AcquireThread(void);
void TimeoutThread(void);
static CppUnit::Test *suite(void);
};
#endif
@@ -1,150 +0,0 @@
/*
$Id: ConstructionTest1.cpp 301 2002-07-18 05:32:00Z tylerdauwalder $
This file implements a test class for testing BLocker construction
functionality. It checks the "Construction 1", "Construction 2" and
"Sem" use cases. It does so by testing all the documented constructors
and uses the Sem() member function to confirm that the name and style
were set correctly.
*/
#include "ConstructionTest1.h"
#include <string.h>
#include <Locker.h>
#include <OS.h>
#include <cppunit/TestCaller.h>
/*
* Method: ConstructionTest1::ConstructionTest1()
* Descr: This is the constructor for this class.
*/
ConstructionTest1::ConstructionTest1(std::string name) :
LockerTestCase(name, true)
{
}
/*
* Method: ConstructionTest1::~ConstructionTest1()
* Descr: This is the desctructor for this BLocker test class.
*/
ConstructionTest1::~ConstructionTest1()
{
}
/*
* Method: ConstructionTest1::NameMatches()
* Descr: This member checks that the semaphore owned by the lock
* passed in has the name passed in.
*/
bool
ConstructionTest1::NameMatches(const char *name,
BLocker *lockerArg)
{
sem_info theSemInfo;
CPPUNIT_ASSERT(get_sem_info(lockerArg->Sem(), &theSemInfo) == B_OK);
return(strcmp(name, theSemInfo.name) == 0);
}
/*
* Method: ConstructionTest1::IsBenaphore()
* Descr: This member attempts to confirm that the BLocker passed in
* is a benaphore or a semaphore style locker. It returns true
* if it is a benaphore, false if it is a semaphore. An
* assertion is raised if an error occurs.
*/
bool
ConstructionTest1::IsBenaphore(BLocker *lockerArg)
{
int32 semCount;
CPPUNIT_ASSERT(get_sem_count(lockerArg->Sem(), &semCount) == B_OK);
switch (semCount) {
case 0: return(true);
break;
case 1: return(false);
break;
default:
// This should not happen. The semaphore count should be
// 0 for a benaphore, 1 for a semaphore. No other value
// is legal in this case.
CPPUNIT_ASSERT(false);
break;
}
return(false);
}
/*
* Method: ConstructionTest1::PerformTest()
* Descr: This member function is used to test each of the constructors
* for the BLocker. The resulting BLocker is tested to show
* that the BLocker was constructed correctly.
*/
void ConstructionTest1::PerformTest(void)
{
NextSubTest();
CPPUNIT_ASSERT(NameMatches("some BLocker", theLocker));
CPPUNIT_ASSERT(IsBenaphore(theLocker));
NextSubTest();
BLocker locker1("test string");
CPPUNIT_ASSERT(NameMatches("test string", &locker1));
CPPUNIT_ASSERT(IsBenaphore(&locker1));
NextSubTest();
BLocker locker2(false);
CPPUNIT_ASSERT(NameMatches("some BLocker", &locker2));
CPPUNIT_ASSERT(!IsBenaphore(&locker2));
NextSubTest();
BLocker locker3(true);
CPPUNIT_ASSERT(NameMatches("some BLocker", &locker3));
CPPUNIT_ASSERT(IsBenaphore(&locker3));
NextSubTest();
BLocker locker4("test string", false);
CPPUNIT_ASSERT(NameMatches("test string", &locker4));
CPPUNIT_ASSERT(!IsBenaphore(&locker4));
NextSubTest();
BLocker locker5("test string", true);
CPPUNIT_ASSERT(NameMatches("test string", &locker5));
CPPUNIT_ASSERT(IsBenaphore(&locker5));
}
/*
* Method: ConstructionTest1::suite()
* Descr: This static member function returns a threaded test caller for
* performing "ConstructionTest1". The threaded test caller
* only has a single thread pointint to the PerformTest() member
* function of this class.
*/
CppUnit::Test *ConstructionTest1::suite(void)
{
typedef CppUnit::TestCaller <ConstructionTest1 >
ConstructionTest1Caller;
return new ConstructionTest1Caller("BLocker::Construction Test", &ConstructionTest1::PerformTest);
}
@@ -1,36 +0,0 @@
/*
$Id: ConstructionTest1.h 301 2002-07-18 05:32:00Z tylerdauwalder $
This file defines a class for performing one test of BLocker
functionality.
*/
#ifndef ConstructionTest1_H
#define ConstructionTest1_H
#include "LockerTestCase.h"
class ConstructionTest1 :
public LockerTestCase {
private:
bool NameMatches(const char *, BLocker *);
bool IsBenaphore(BLocker *);
protected:
public:
void PerformTest(void);
ConstructionTest1(std::string name = "");
virtual ~ConstructionTest1();
static CppUnit::Test *suite(void);
};
#endif
@@ -1,140 +0,0 @@
/*
$Id: DestructionTest1.cpp 301 2002-07-18 05:32:00Z tylerdauwalder $
This file implements a test class for testing BLocker functionality.
It tests use cases "Destruction" and "Locking 3".
The test works like the following:
- the main thread acquires the lock
- the second thread sleeps
- the second thread then attempts to acquire the lock
- the first thread releases the lock
- at this time, the new thread acquires the lock and goes to sleep
- the first thread attempts to acquire the lock
- the second thread deletes the lock
- the first thread is woken up indicating that the lock wasn't acquired.
*/
#include "ThreadedTestCaller.h"
#include "DestructionTest1.h"
#include "cppunit/TestSuite.h"
#include <Locker.h>
// This constant is used to determine the number of microseconds to
// sleep during major steps of the test.
const bigtime_t SNOOZE_TIME = 200000;
/*
* Method: DestructionTest1::DestructionTest1()
* Descr: This is the only constructor for this test class.
*/
DestructionTest1::DestructionTest1(std::string name,
bool isBenaphore) :
LockerTestCase(name, isBenaphore)
{
}
/*
* Method: DestructionTest1::~DestructionTest1()
* Descr: This is the only destructor for this test class.
*/
DestructionTest1::~DestructionTest1()
{
}
/*
* Method: DestructionTest1::TestThread1()
* Descr: This method immediately acquires the lock, sleeps
* for SNOOZE_TIME and then releases the lock. It sleeps
* again for SNOOZE_TIME and then tries to re-acquire the
* lock. By this time, the other thread should have
* deleted the lock. This acquisition should fail.
*/
void DestructionTest1::TestThread1(void)
{
CPPUNIT_ASSERT(theLocker->Lock());
NextSubTest();
snooze(SNOOZE_TIME);
NextSubTest();
theLocker->Unlock();
NextSubTest();
snooze(SNOOZE_TIME);
NextSubTest();
CPPUNIT_ASSERT(!theLocker->Lock());
NextSubTest();
}
/*
* Method: DestructionTest1::TestThread2()
* Descr: This method sleeps for SNOOZE_TIME and then acquires the lock.
* It sleeps again for 2*SNOOZE_TIME and then deletes the lock.
* This should wake up the other thread.
*/
void DestructionTest1::TestThread2(void)
{
BLocker *tmpLock;
snooze(SNOOZE_TIME);
NextSubTest();
CPPUNIT_ASSERT(theLocker->Lock());
NextSubTest();
snooze(SNOOZE_TIME);
NextSubTest();
snooze(SNOOZE_TIME);
NextSubTest();
tmpLock = theLocker;
NextSubTest();
theLocker = NULL;
NextSubTest();
delete tmpLock;
}
/*
* Method: DestructionTest1::suite()
* Descr: This static member function returns a test suite for performing
* all combinations of "DestructionTest1". The test suite contains
* two instances of the test. One is performed on a benaphore,
* the other on a semaphore based BLocker. Each individual test
* is created as a ThreadedTestCase (typedef'd as
* DestructionTest1Caller) with two independent threads.
*/
CppUnit::Test *DestructionTest1::suite(void)
{
typedef BThreadedTestCaller <DestructionTest1 >
DestructionTest1Caller;
CppUnit::TestSuite *testSuite = new CppUnit::TestSuite("DestructionTest1");
// Make a benaphore based test object, create a ThreadedTestCase for it and add
// two threads to it.
DestructionTest1 *theTest = new DestructionTest1("Benaphore", true);
DestructionTest1Caller *threadedTest1 = new DestructionTest1Caller("BLocker::Destruction Test #1 (benaphore)", theTest);
threadedTest1->addThread("A", &DestructionTest1::TestThread1);
threadedTest1->addThread("B", &DestructionTest1::TestThread2);
// Make a semaphore based test object, create a ThreadedTestCase for it and add
// three threads to it.
theTest = new DestructionTest1("Semaphore", false);
DestructionTest1Caller *threadedTest2 = new DestructionTest1Caller("BLocker::Destruction Test #1 (semaphore)", theTest);
threadedTest2->addThread("A", &DestructionTest1::TestThread1);
threadedTest2->addThread("B", &DestructionTest1::TestThread2);
testSuite->addTest(threadedTest1);
testSuite->addTest(threadedTest2);
return(testSuite);
}
@@ -1,33 +0,0 @@
/*
$Id: DestructionTest1.h 301 2002-07-18 05:32:00Z tylerdauwalder $
This file defines a class for performing one test of BLocker
functionality.
*/
#ifndef DestructionTest1_H
#define DestructionTest1_H
#include "LockerTestCase.h"
#include <string>
class DestructionTest1 : public LockerTestCase {
private:
protected:
public:
void TestThread1(void);
void TestThread2(void);
DestructionTest1(std::string name, bool isBenaphore);
virtual ~DestructionTest1();
static CppUnit::Test *suite(void);
};
#endif
@@ -1,146 +0,0 @@
/*
$Id: DestructionTest2.cpp 301 2002-07-18 05:32:00Z tylerdauwalder $
This file implements a test class for testing BLocker functionality.
It tests use cases "Destruction" and "Locking 4".
The test works like the following:
- the main thread acquires the lock
- it creates a new thread and sleeps
- the new thread attempts to acquire the lock but times out
- the new thread then attempts to acquire the lock again
- before the new thread times out a second time, the first thread releases
the lock
- at this time, the new thread acquires the lock and goes to sleep
- the first thread attempts to acquire the lock
- the second thread deletes the lock
- the first thread is woken up indicating that the lock wasn't acquired.
*/
#include <ThreadedTestCaller.h>
#include "DestructionTest2.h"
#include <cppunit/TestSuite.h>
#include <Locker.h>
// This constant is used to determine the number of microseconds to
// sleep during major steps of the test.
const bigtime_t SNOOZE_TIME = 200000;
/*
* Method: DestructionTest2::DestructionTest2()
* Descr: This is the only constructor for this test class.
*/
DestructionTest2::DestructionTest2(std::string name,
bool isBenaphore) :
LockerTestCase(name, isBenaphore)
{
}
/*
* Method: DestructionTest2::~DestructionTest2()
* Descr: This is the only destructor for this test class.
*/
DestructionTest2::~DestructionTest2()
{
}
/*
* Method: DestructionTest2::TestThread1()
* Descr: This method immediately acquires the lock, sleeps
* for SNOOZE_TIME and then releases the lock. It sleeps
* again for SNOOZE_TIME and then tries to re-acquire the
* lock. By this time, the other thread should have
* deleted the lock. This acquisition should fail.
*/
void DestructionTest2::TestThread1(void)
{
CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME) == B_OK);
NextSubTest();
snooze(SNOOZE_TIME);
NextSubTest();
theLocker->Unlock();
NextSubTest();
snooze(SNOOZE_TIME);
NextSubTest();
CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME * 10) == B_BAD_SEM_ID);
NextSubTest();
}
/*
* Method: DestructionTest2::TestThread2()
* Descr: This method sleeps for SNOOZE_TIME/10 and then attempts to acquire
* the lock for SNOOZE_TIME/10 seconds. This acquisition will timeout
* because the other thread is holding the lock. Then it acquires the
* lock by using a larger timeout. It sleeps again for 2*SNOOZE_TIME and
* then deletes the lock. This should wake up the other thread.
*/
void DestructionTest2::TestThread2(void)
{
BLocker *tmpLock;
snooze(SNOOZE_TIME/10);
NextSubTest();
CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT);
NextSubTest();
CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME * 10) == B_OK);
NextSubTest();
snooze(SNOOZE_TIME);
NextSubTest();
snooze(SNOOZE_TIME);
NextSubTest();
tmpLock = theLocker;
theLocker = NULL;
delete tmpLock;
}
/*
* Method: DestructionTest2::suite()
* Descr: This static member function returns a test suite for performing
* all combinations of "DestructionTest2". The test suite contains
* two instances of the test. One is performed on a benaphore,
* the other on a semaphore based BLocker. Each individual test
* is created as a ThreadedTestCase (typedef'd as
* DestructionTest2Caller) with two independent threads.
*/
CppUnit::Test *DestructionTest2::suite(void)
{
typedef BThreadedTestCaller<DestructionTest2> DestructionTest2Caller;
CppUnit::TestSuite *testSuite = new CppUnit::TestSuite("DestructionTest2");
// Make a benaphore based test object, create a ThreadedTestCase for it and add
// two threads to it.
DestructionTest2 *theTest = new DestructionTest2("Benaphore", true);
DestructionTest2Caller *threadedTest1 = new DestructionTest2Caller("BLocker::Destruction Test #2 (benaphore)", theTest);
threadedTest1->addThread("A", &DestructionTest2::TestThread1);
threadedTest1->addThread("B", &DestructionTest2::TestThread2);
// Make a semaphore based test object, create a ThreadedTestCase for it and add
// three threads to it.
theTest = new DestructionTest2("Semaphore", false);
DestructionTest2Caller *threadedTest2 = new DestructionTest2Caller("BLocker::Destruction Test #2 (semaphore)", theTest);
threadedTest2->addThread("A", &DestructionTest2::TestThread1);
threadedTest2->addThread("B", &DestructionTest2::TestThread2);
testSuite->addTest(threadedTest1);
testSuite->addTest(threadedTest2);
return(testSuite);
}
@@ -1,29 +0,0 @@
/*
$Id: DestructionTest2.h 301 2002-07-18 05:32:00Z tylerdauwalder $
This file defines a class for performing one test of BLocker
functionality.
*/
#ifndef DestructionTest2_H
#define DestructionTest2_H
#include "LockerTestCase.h"
class CppUnit::Test;
class DestructionTest2 : public LockerTestCase {
public:
void TestThread1(void);
void TestThread2(void);
DestructionTest2(std::string name, bool isBenaphore);
virtual ~DestructionTest2();
static CppUnit::Test *suite(void);
};
#endif
@@ -1,50 +0,0 @@
/*
$Id: LockerTest.cpp 301 2002-07-18 05:32:00Z tylerdauwalder $
This file declares the addonTestName string and addonTestFunc
function for the BLocker tests. These symbols will be used
when the addon is loaded.
*/
#include "ConstructionTest1.h"
#include "ConcurrencyTest1.h"
#include "ConcurrencyTest2.h"
#include "DestructionTest1.h"
#include "DestructionTest2.h"
#include "BenaphoreLockCountTest1.h"
#include "SemaphoreLockCountTest1.h"
#include "LockerTest.h"
#include "cppunit/Test.h"
#include "cppunit/TestSuite.h"
/*
* Function: addonTestFunc()
* Descr: This function is called by the test application to
* get a pointer to the test to run. The BLocker test
* is a test suite. A series of tests are added to
* the suite. Each test appears twice, once for
* the Be implementation of BLocker, once for the
* Haiku implementation.
*/
CppUnit::Test* LockerTestSuite()
{
CppUnit::TestSuite *testSuite = new CppUnit::TestSuite();
testSuite->addTest(ConstructionTest1::suite());
// testSuite->addTest(ConcurrencyTest1::suite());
// testSuite->addTest(ConcurrencyTest2::suite());
testSuite->addTest(DestructionTest1::suite());
testSuite->addTest(DestructionTest2::suite());
// testSuite->addTest(BenaphoreLockCountTest1::suite());
// testSuite->addTest(SemaphoreLockCountTest1::suite());
return testSuite;
}
@@ -1,8 +0,0 @@
#ifndef _locker_test_file_h_
#define _locker_test_file_h_
class CppUnit::Test;
CppUnit::Test* LockerTestSuite();
#endif // _locker_test_h_
@@ -1,74 +0,0 @@
/*
$Id: LockerTestCase.cpp 301 2002-07-18 05:32:00Z tylerdauwalder $
This file implements a base class for testing BLocker functionality.
*/
#include "LockerTestCase.h"
#include <Locker.h>
/*
* Method: LockerTestCase::LockerTestCase()
* Descr: This method is the only constructore for the LockerTestCase
* class. It takes a test name and a flag to indicate whether
* the locker should be a benaphore or a semaphore.
*/
LockerTestCase::LockerTestCase(std::string name, bool isBenaphore) :
BThreadedTestCase(name), theLocker(new BLocker(isBenaphore))
{
}
/*
* Method: LockerTestCase::~LockerTestCase()
* Descr: This method is the destructor for the LockerTestCase class.
* It only deallocates the locker allocated in the constructor.
*/
LockerTestCase::~LockerTestCase()
{
delete theLocker;
theLocker = NULL;
}
/*
* Method: LockerTestCase::CheckLock()
* Descr: This method confirms that the lock is currently in a sane
* state. If the lock is not sane, then an assertion is
* raised. The caller provides the number of times the
* thread has successfully acquired the lock. If the caller
* indicates that the lock has been acquired one or more times
* by the current thread, then the function confirms that. If
* the caller indicates the lock has not been acquired
* (expectedCount = 0), then it checks to make sure that the
* lock is not held by the current thread. If it is, it
* raises an assertion.
*/
void LockerTestCase::CheckLock(int expectedCount)
{
bool isLocked = theLocker->IsLocked();
thread_id actualThread = theLocker->LockingThread();
thread_id expectedThread = find_thread(NULL);
int32 actualCount = theLocker->CountLocks();
if (expectedCount > 0) {
CPPUNIT_ASSERT(isLocked);
CPPUNIT_ASSERT(expectedThread == actualThread);
CPPUNIT_ASSERT(expectedCount == actualCount);
} else {
CPPUNIT_ASSERT(!((isLocked) && (actualThread == expectedThread)));
}
return;
}
@@ -1,65 +0,0 @@
/*
$Id: LockerTestCase.h 301 2002-07-18 05:32:00Z tylerdauwalder $
This file defines a couple of common classes for testing BLocker
functionality.
*/
#ifndef LockerTestCase_H
#define LockerTestCase_H
#include <ThreadedTestCase.h>
#include <string>
class BLocker;
//
// The SafetyLock class is a utility class for use in actual tests
// of the BLocker interfaces. It is used to make sure that if the
// test fails and an exception is thrown with the lock held, that
// lock will be released. Without this SafetyLock, there could be
// deadlocks if one thread in a test has a failure while holding the
// lock. It should be used like so:
//
// void myTestClass::myTestFunc(void)
// {
// SafetyLock mySafetyLock(theLocker);
// ...perform tests without worrying about holding the lock on assert...
//
class SafetyLock {
private:
BLocker *theLocker;
public:
SafetyLock(BLocker *aLock) {theLocker = aLock;};
virtual ~SafetyLock() {if (theLocker != NULL) theLocker->Unlock(); };
};
//
// All BLocker tests should be derived from the LockerTestCase class.
// This class provides a BLocker allocated on construction to the
// derived class. This BLocker is the member "theLocker". Also,
// there is a member function called CheckLock() which ensures that
// the lock is sane.
//
class LockerTestCase : public BThreadedTestCase {
protected:
BLocker *theLocker;
void CheckLock(int);
public:
LockerTestCase(std::string name, bool);
virtual ~LockerTestCase();
};
#endif
@@ -1,195 +0,0 @@
/*
$Id: SemaphoreLockCountTest1.cpp 301 2002-07-18 05:32:00Z tylerdauwalder $
This file implements a test class for testing BLocker functionality.
It tests use cases "Count Lock Requests" for a semaphore style BLocker.
The test works by:
- checking the lock requests
- acquiring the lock
- checking the lock requests
- staring a thread which times out acquiring the lock and then blocks
again waiting for the lock
- checking the lock requests
- start a second thread which times out acquiring the lock and then blocks
again waiting for the lock
- checking the lock requests
- release the lock
- each blocked thread acquires the lock, checks the lock requests and releases
the lock before terminating
- the main thread checks the lock requests one last time
*/
#include "ThreadedTestCaller.h"
#include "SemaphoreLockCountTest1.h"
#include "cppunit/TestSuite.h"
#include <Locker.h>
// This constant is used to determine the number of microseconds to
// sleep during major steps of the test.
const bigtime_t SNOOZE_TIME = 100000;
/*
* Method: SemaphoreLockCountTest1::SemaphoreLockCountTest1()
* Descr: This is the constructor for this test class.
*/
SemaphoreLockCountTest1::SemaphoreLockCountTest1(std::string name) :
LockerTestCase(name, false)
{
}
/*
* Method: SemaphoreLockCountTest1::~SemaphoreLockCountTest1()
* Descr: This is the destructor for this test class.
*/
SemaphoreLockCountTest1::~SemaphoreLockCountTest1()
{
}
/*
* Method: SemaphoreLockCountTest1::CheckLockRequests()
* Descr: This member function checks the actual number of lock requests
* that the BLocker thinks are outstanding versus the number
* passed in. If they match, true is returned.
*/
bool SemaphoreLockCountTest1::CheckLockRequests(int expected)
{
int actual = theLocker->CountLockRequests();
return(actual == expected);
}
/*
* Method: SemaphoreLockCountTest1::TestThread1()
* Descr: This member function performs the main portion of the test.
* It first acquires thread2Lock and thread3Lock. This ensures
* that thread2 and thread3 will block until this thread wants
* them to start running. It then checks the lock count, acquires
* the lock and checks the lock count again. It unlocks each
* of the other two threads in turn and rechecks the lock count.
* Finally, it releases the lock and sleeps for a short while
* for the other two threads to finish. At the end, it checks
* the lock count on final time.
*/
void SemaphoreLockCountTest1::TestThread1(void)
{
SafetyLock theSafetyLock1(theLocker);
SafetyLock theSafetyLock2(&thread2Lock);
SafetyLock theSafetyLock3(&thread3Lock);
NextSubTest();
CPPUNIT_ASSERT(thread2Lock.Lock());
CPPUNIT_ASSERT(thread3Lock.Lock());
NextSubTest();
CPPUNIT_ASSERT(CheckLockRequests(1));
CPPUNIT_ASSERT(theLocker->Lock());
NextSubTest();
CPPUNIT_ASSERT(CheckLockRequests(2));
NextSubTest();
thread2Lock.Unlock();
snooze(SNOOZE_TIME);
CPPUNIT_ASSERT(CheckLockRequests(4));
NextSubTest();
thread3Lock.Unlock();
snooze(SNOOZE_TIME);
CPPUNIT_ASSERT(CheckLockRequests(6));
NextSubTest();
theLocker->Unlock();
snooze(SNOOZE_TIME);
CPPUNIT_ASSERT(CheckLockRequests(3));
}
/*
* Method: SemaphoreLockCountTest1::TestThread2()
* Descr: This member function defines the actions of the second thread of
* the test. First it sleeps for a short while and then blocks on
* the thread2Lock. When the first thread releases it, this thread
* begins its testing. It times out attempting to acquire the main
* lock and then blocks to acquire the lock. Once that lock is
* acquired, the lock count is checked before finishing this thread.
*/
void SemaphoreLockCountTest1::TestThread2(void)
{
SafetyLock theSafetyLock1(theLocker);
NextSubTest();
snooze(SNOOZE_TIME / 10);
CPPUNIT_ASSERT(thread2Lock.Lock());
NextSubTest();
CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT);
CPPUNIT_ASSERT(theLocker->Lock());
int actual = theLocker->CountLockRequests();
CPPUNIT_ASSERT((actual == 4) || (actual == 5));
theLocker->Unlock();
}
/*
* Method: SemaphoreLockCountTest1::TestThread3()
* Descr: This member function defines the actions of the second thread of
* the test. First it sleeps for a short while and then blocks on
* the thread3Lock. When the first thread releases it, this thread
* begins its testing. It times out attempting to acquire the main
* lock and then blocks to acquire the lock. Once that lock is
* acquired, the lock count is checked before finishing this thread.
*/
void SemaphoreLockCountTest1::TestThread3(void)
{
SafetyLock theSafetyLock1(theLocker);
NextSubTest();
snooze(SNOOZE_TIME / 10);
CPPUNIT_ASSERT(thread3Lock.Lock());
NextSubTest();
CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT);
CPPUNIT_ASSERT(theLocker->Lock());
int actual = theLocker->CountLockRequests();
CPPUNIT_ASSERT((actual == 4) || (actual == 5));
theLocker->Unlock();
}
/*
* Method: SemaphoreLockCountTest1::suite()
* Descr: This static member function returns a test caller for performing
* the "SemaphoreLockCountTest1" test. The test caller
* is created as a ThreadedTestCaller (typedef'd as
* SemaphoreLockCountTest1Caller) with three independent threads.
*/
CppUnit::Test *SemaphoreLockCountTest1::suite(void)
{
typedef BThreadedTestCaller <SemaphoreLockCountTest1 >
SemaphoreLockCountTest1Caller;
SemaphoreLockCountTest1 *theTest = new SemaphoreLockCountTest1("");
SemaphoreLockCountTest1Caller *threadedTest = new SemaphoreLockCountTest1Caller("BLocker::Semaphore Lock Count Test", theTest);
threadedTest->addThread("A", &SemaphoreLockCountTest1::TestThread1);
threadedTest->addThread("B", &SemaphoreLockCountTest1::TestThread2);
threadedTest->addThread("C", &SemaphoreLockCountTest1::TestThread3);
return(threadedTest);
}
@@ -1,41 +0,0 @@
/*
$Id: SemaphoreLockCountTest1.h 301 2002-07-18 05:32:00Z tylerdauwalder $
This file defines a classes for performing one test of BLocker
functionality.
*/
#ifndef SemaphoreLockCountTest1_H
#define SemaphoreLockCountTest1_H
#include "LockerTestCase.h"
#include <string>
class SemaphoreLockCountTest1 :
public LockerTestCase {
private:
BLocker thread2Lock;
BLocker thread3Lock;
bool CheckLockRequests(int);
protected:
public:
void TestThread1(void);
void TestThread2(void);
void TestThread3(void);
SemaphoreLockCountTest1(std::string);
virtual ~SemaphoreLockCountTest1();
static Test *suite(void);
};
#endif
@@ -1,53 +0,0 @@
#include "ConstTest.h"
#include "cppunit/TestCaller.h"
#include <DataIO.h>
#include <stdio.h>
#include <string.h>
ConstTest::ConstTest(std::string name) :
BTestCase(name)
{
}
ConstTest::~ConstTest()
{
}
void
ConstTest::PerformTest(void)
{
const char buf[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
BMemoryIO mem(buf, 10);
status_t err;
NextSubTest();
err = mem.SetSize(4);
CPPUNIT_ASSERT(err == B_NOT_ALLOWED);
NextSubTest();
err = mem.SetSize(20);
CPPUNIT_ASSERT(err == B_NOT_ALLOWED);
NextSubTest();
char readBuf[10] = "";
err = mem.Write(readBuf, 3);
CPPUNIT_ASSERT(err == B_NOT_ALLOWED);
CPPUNIT_ASSERT(strcmp(readBuf, "") == 0);
NextSubTest();
err = mem.WriteAt(2, readBuf, 1);
CPPUNIT_ASSERT(err == B_NOT_ALLOWED);
CPPUNIT_ASSERT(strcmp(readBuf, "") == 0);
}
CppUnit::Test *ConstTest::suite(void)
{
typedef CppUnit::TestCaller<ConstTest>
ConstTestCaller;
return(new ConstTestCaller("BMemoryIO::Const Test", &ConstTest::PerformTest));
}
@@ -1,22 +0,0 @@
#ifndef ConstTest_H
#define ConstTest_H
#include "TestCase.h"
#include <DataIO.h>
class ConstTest : public BTestCase
{
private:
protected:
public:
static Test *suite(void);
void PerformTest(void);
ConstTest(std::string name = "");
virtual ~ConstTest();
};
#endif
@@ -1,68 +0,0 @@
#include "MallocBufferLengthTest.h"
#include "cppunit/TestCaller.h"
#include <DataIO.h>
#include <stdio.h>
MallocBufferLengthTest::MallocBufferLengthTest(std::string name) :
BTestCase(name)
{
}
MallocBufferLengthTest::~MallocBufferLengthTest()
{
}
void
MallocBufferLengthTest::PerformTest(void)
{
BMallocIO mem;
size_t size;
size_t bufLen;
status_t error;
off_t offset;
char writeBuf[11] = "0123456789";
NextSubTest();
bufLen = mem.BufferLength();
CPPUNIT_ASSERT(bufLen == 0);
NextSubTest();
size = mem.Write(writeBuf, 10);
bufLen = mem.BufferLength();
CPPUNIT_ASSERT(bufLen == 10);
CPPUNIT_ASSERT(size = 10);
NextSubTest();
error = mem.SetSize(0);
bufLen = mem.BufferLength();
CPPUNIT_ASSERT(bufLen == 0);
CPPUNIT_ASSERT(error == B_OK);
//This is for the BResource crashing bug
NextSubTest();
error = mem.SetSize(200);
bufLen = mem.BufferLength();
offset = mem.Seek(0, SEEK_END);
CPPUNIT_ASSERT(bufLen == 200);
CPPUNIT_ASSERT(error == B_OK);
CPPUNIT_ASSERT(offset == 200);
NextSubTest();
offset = mem.Seek(0, SEEK_END);
error = mem.SetSize(100);
bufLen = mem.BufferLength();
CPPUNIT_ASSERT(bufLen == 100);
CPPUNIT_ASSERT(mem.Position() == offset);
}
CppUnit::Test *MallocBufferLengthTest::suite(void)
{
typedef CppUnit::TestCaller<MallocBufferLengthTest>
MallocBufferLengthTestCaller;
return(new MallocBufferLengthTestCaller("BMallocIO::BufferLength Test", &MallocBufferLengthTest::PerformTest));
}
@@ -1,22 +0,0 @@
#ifndef MallocBufferLengthTest_H
#define MallocBufferLengthTest_H
#include "TestCase.h"
#include <DataIO.h>
class MallocBufferLengthTest : public BTestCase
{
private:
protected:
public:
static Test *suite(void);
void PerformTest(void);
MallocBufferLengthTest(std::string name = "");
virtual ~MallocBufferLengthTest();
};
#endif
@@ -1,24 +0,0 @@
#include "cppunit/Test.h"
#include "cppunit/TestSuite.h"
#include "MallocIOTest.h"
#include "MallocSeekTest.h"
#include "MallocWriteTest.h"
#include "MallocBufferLengthTest.h"
CppUnit::Test *MallocIOTestSuite()
{
CppUnit::TestSuite *testSuite = new CppUnit::TestSuite();
testSuite->addTest(MallocSeekTest::suite());
testSuite->addTest(MallocWriteTest::suite());
testSuite->addTest(MallocBufferLengthTest::suite());
return(testSuite);
}
@@ -1,14 +0,0 @@
#ifndef _mallocio_test_h_
#define _mallocio_test_h_
class CppUnit::Test;
CppUnit::Test *MallocIOTestSuite();
#endif // _mallocio_test_h_
@@ -1,56 +0,0 @@
#include "MallocSeekTest.h"
#include "cppunit/TestCaller.h"
#include <DataIO.h>
#include <stdio.h>
MallocSeekTest::MallocSeekTest(std::string name) :
BTestCase(name)
{
}
MallocSeekTest::~MallocSeekTest()
{
}
void
MallocSeekTest::PerformTest(void)
{
BMallocIO mem;
off_t err;
NextSubTest();
err = mem.Seek(3, SEEK_SET);
CPPUNIT_ASSERT(err == 3);
NextSubTest();
err = mem.Seek(3, SEEK_CUR);
CPPUNIT_ASSERT(err == 6);
NextSubTest();
err = mem.Seek(0, SEEK_END);
CPPUNIT_ASSERT(err == 0);
NextSubTest();
err = mem.Seek(-5, SEEK_END);
CPPUNIT_ASSERT(err == -5);
NextSubTest();
err = mem.Seek(5, SEEK_END);
CPPUNIT_ASSERT(err == 5);
NextSubTest();
err = mem.Seek(-20, SEEK_SET);
CPPUNIT_ASSERT((int)err == -20);
}
CppUnit::Test *MallocSeekTest::suite(void)
{
typedef CppUnit::TestCaller<MallocSeekTest>
MallocSeekTestCaller;
return(new MallocSeekTestCaller("BMallocIO::Seek Test", &MallocSeekTest::PerformTest));
}
@@ -1,22 +0,0 @@
#ifndef MallocSeekTest_H
#define MallocSeekTest_H
#include "TestCase.h"
#include <DataIO.h>
class MallocSeekTest : public BTestCase
{
private:
protected:
public:
static Test *suite(void);
void PerformTest(void);
MallocSeekTest(std::string name = "");
virtual ~MallocSeekTest();
};
#endif
@@ -1,47 +0,0 @@
#include "MallocWriteTest.h"
#include "cppunit/TestCaller.h"
#include <DataIO.h>
#include <stdio.h>
#include <string.h>
MallocWriteTest::MallocWriteTest(std::string name) :
BTestCase(name)
{
}
MallocWriteTest::~MallocWriteTest()
{
}
void
MallocWriteTest::PerformTest(void)
{
const char *writeBuf = "ABCDEFG";
BMallocIO mem;
ssize_t err;
NextSubTest();
err = mem.Write(writeBuf, 7);
CPPUNIT_ASSERT(err == 7); // Check how much data we wrote
NextSubTest();
err = mem.WriteAt(0, writeBuf, 4);
CPPUNIT_ASSERT(err == 4);
NextSubTest();
err = mem.WriteAt(34, writeBuf, 256);
CPPUNIT_ASSERT(err == 256);
}
CppUnit::Test *MallocWriteTest::suite(void)
{
typedef CppUnit::TestCaller<MallocWriteTest>
MallocWriteTestCaller;
return(new MallocWriteTestCaller("BMallocIO::Write Test", &MallocWriteTest::PerformTest));
}
@@ -1,22 +0,0 @@
#ifndef MallocWriteTest_H
#define MallocWriteTest_H
#include "TestCase.h"
#include <DataIO.h>
class MallocWriteTest : public BTestCase
{
private:
protected:
public:
static Test *suite(void);
void PerformTest(void);
MallocWriteTest(std::string name = "");
virtual ~MallocWriteTest();
};
#endif
@@ -1,28 +0,0 @@
#include "cppunit/Test.h"
#include "cppunit/TestSuite.h"
#include "MemoryIOTest.h"
#include "ConstTest.h"
#include "SeekTest.h"
#include "WriteTest.h"
#include "ReadTest.h"
#include "SetSizeTest.h"
CppUnit::Test *MemoryIOTestSuite()
{
CppUnit::TestSuite *testSuite = new CppUnit::TestSuite();
testSuite->addTest(ConstTest::suite());
testSuite->addTest(SeekTest::suite());
testSuite->addTest(WriteTest::suite());
testSuite->addTest(ReadTest::suite());
testSuite->addTest(SetSizeTest::suite());
return(testSuite);
}
@@ -1,14 +0,0 @@
#ifndef _memoryio_test_h_
#define _memoryio_test_h_
class CppUnit::Test;
CppUnit::Test *MemoryIOTestSuite();
#endif // _memoryio_test_h_
@@ -1,59 +0,0 @@
#include "ReadTest.h"
#include "cppunit/TestCaller.h"
#include <DataIO.h>
#include <stdio.h>
#include <string.h>
ReadTest::ReadTest(std::string name) :
BTestCase(name)
{
}
ReadTest::~ReadTest()
{
}
void
ReadTest::PerformTest(void)
{
char buf[20] = "0123456789ABCDEFGHI";
char readBuf[10];
memset(readBuf, 0, 10);
BMemoryIO mem(buf, 20);
ssize_t err;
off_t pos;
NextSubTest();
pos = mem.Position();
err = mem.Read(readBuf, 10);
CPPUNIT_ASSERT(err == 10);
CPPUNIT_ASSERT(strncmp(readBuf, buf, 10) == 0);
CPPUNIT_ASSERT(mem.Position() == pos + err);
NextSubTest();
pos = mem.Position();
err = mem.ReadAt(30, readBuf, 10);
CPPUNIT_ASSERT(err == 0);
CPPUNIT_ASSERT(mem.Position() == pos);
NextSubTest();
pos = mem.Seek(0, SEEK_END);
err = mem.Read(readBuf, 10);
CPPUNIT_ASSERT(err == 0);
CPPUNIT_ASSERT(mem.Position() == pos);
}
CppUnit::Test *ReadTest::suite(void)
{
typedef CppUnit::TestCaller<ReadTest>
ReadTestCaller;
return(new ReadTestCaller("BMemoryIO::Read Test", &ReadTest::PerformTest));
}
@@ -1,22 +0,0 @@
#ifndef ReadTest_H
#define ReadTest_H
#include "TestCase.h"
#include <DataIO.h>
class ReadTest : public BTestCase
{
private:
protected:
public:
static Test *suite(void);
void PerformTest(void);
ReadTest(std::string name = "");
virtual ~ReadTest();
};
#endif
@@ -1,53 +0,0 @@
#include "SeekTest.h"
#include "cppunit/TestCaller.h"
#include <DataIO.h>
#include <stdio.h>
SeekTest::SeekTest(std::string name) :
BTestCase(name)
{
}
SeekTest::~SeekTest()
{
}
void
SeekTest::PerformTest(void)
{
char buf[10];
BMemoryIO mem(buf, 10);
off_t err;
NextSubTest();
err = mem.Seek(3, SEEK_SET);
CPPUNIT_ASSERT(err == 3);
NextSubTest();
err = mem.Seek(3, SEEK_CUR);
CPPUNIT_ASSERT(err == 6);
NextSubTest();
err = mem.Seek(0, SEEK_END);
CPPUNIT_ASSERT(err == 10);
NextSubTest();
err = mem.Seek(-5, SEEK_END);
CPPUNIT_ASSERT(err == 5);
NextSubTest();
err = mem.Seek(5, SEEK_END);
CPPUNIT_ASSERT(err == 15);
}
CppUnit::Test *SeekTest::suite(void)
{
typedef CppUnit::TestCaller<SeekTest>
SeekTestCaller;
return(new SeekTestCaller("BMemoryIO::Seek Test", &SeekTest::PerformTest));
}
@@ -1,22 +0,0 @@
#ifndef SeekTest_H
#define SeekTest_H
#include "TestCase.h"
#include <DataIO.h>
class SeekTest : public BTestCase
{
private:
protected:
public:
static Test *suite(void);
void PerformTest(void);
SeekTest(std::string name = "");
virtual ~SeekTest();
};
#endif
@@ -1,60 +0,0 @@
#include "SetSizeTest.h"
#include "cppunit/TestCaller.h"
#include <DataIO.h>
#include <stdio.h>
#include <string.h>
SetSizeTest::SetSizeTest(std::string name) :
BTestCase(name)
{
}
SetSizeTest::~SetSizeTest()
{
}
void
SetSizeTest::PerformTest(void)
{
char buf[20] = "0123456789ABCDEFGHI";
char readBuf[10];
memset(readBuf, 0, 10);
BMemoryIO mem(buf, 10);
ssize_t size;
off_t pos;
status_t err;
NextSubTest();
err = mem.SetSize(5);
pos = mem.Seek(0, SEEK_END);
size = mem.WriteAt(10, readBuf, 3);
CPPUNIT_ASSERT(err == B_OK);
CPPUNIT_ASSERT(pos == 5);
CPPUNIT_ASSERT(size == 0);
NextSubTest();
err = mem.SetSize(10);
pos = mem.Seek(0, SEEK_END);
size = mem.WriteAt(5, readBuf, 6);
CPPUNIT_ASSERT(err == B_OK);
CPPUNIT_ASSERT(pos == 10);
CPPUNIT_ASSERT(size == 5);
NextSubTest();
err = mem.SetSize(20);
CPPUNIT_ASSERT(err == B_ERROR);
}
CppUnit::Test *SetSizeTest::suite(void)
{
typedef CppUnit::TestCaller<SetSizeTest>
SetSizeTestCaller;
return(new SetSizeTestCaller("BMemoryIO::SetSize Test", &SetSizeTest::PerformTest));
}
@@ -1,22 +0,0 @@
#ifndef SetSizeTest_H
#define SetSizeTest_H
#include "TestCase.h"
#include <DataIO.h>
class SetSizeTest : public BTestCase
{
private:
protected:
public:
static Test *suite(void);
void PerformTest(void);
SetSizeTest(std::string name = "");
virtual ~SetSizeTest();
};
#endif
@@ -1,76 +0,0 @@
#include "WriteTest.h"
#include "cppunit/TestCaller.h"
#include <DataIO.h>
#include <stdio.h>
#include <string.h>
WriteTest::WriteTest(std::string name) :
BTestCase(name)
{
}
WriteTest::~WriteTest()
{
}
void
WriteTest::PerformTest(void)
{
char buf[10];
const char *writeBuf = "ABCDEFG";
BMemoryIO mem(buf, 10);
ssize_t err;
off_t pos;
NextSubTest();
memset(buf, 0, 10);
pos = mem.Position();
err = mem.Write(writeBuf, 7);
CPPUNIT_ASSERT(err == 7); // Check how much data we wrote
CPPUNIT_ASSERT(strcmp(writeBuf, buf) == 0); // Check if we wrote it correctly
CPPUNIT_ASSERT(mem.Position() == pos + err); // Check if Position changed
NextSubTest();
memset(buf, 0, 10);
pos = mem.Position();
err = mem.WriteAt(3, writeBuf, 2);
CPPUNIT_ASSERT(err == 2);
CPPUNIT_ASSERT(strncmp(buf + 3, writeBuf, 2) == 0);
CPPUNIT_ASSERT(mem.Position() == pos);
NextSubTest();
memset(buf, 0, 10);
pos = mem.Position();
err = mem.WriteAt(9, writeBuf, 5);
CPPUNIT_ASSERT(err == 1);
CPPUNIT_ASSERT(strncmp(buf + 9, writeBuf, 1) == 0);
CPPUNIT_ASSERT(mem.Position() == pos);
NextSubTest();
memset(buf, 0, 10);
pos = mem.Position();
err = mem.WriteAt(-10, writeBuf, 5);
CPPUNIT_ASSERT(err == B_BAD_VALUE);
CPPUNIT_ASSERT(mem.Position() == pos);
NextSubTest();
memset(buf, 0, 10);
BMemoryIO read_only_mem(const_cast<const char*>(buf), 10);
pos = read_only_mem.Position();
err = read_only_mem.WriteAt(3, writeBuf, 2);
CPPUNIT_ASSERT(err == B_NOT_ALLOWED);
CPPUNIT_ASSERT(read_only_mem.Position() == pos);
}
CppUnit::Test *WriteTest::suite(void)
{
typedef CppUnit::TestCaller<WriteTest>
WriteTestCaller;
return(new WriteTestCaller("BMemoryIO::Write Test", &WriteTest::PerformTest));
}
@@ -1,22 +0,0 @@
#ifndef WriteTest_H
#define WriteTest_H
#include "TestCase.h"
#include <DataIO.h>
class WriteTest : public BTestCase
{
private:
protected:
public:
static Test *suite(void);
void PerformTest(void);
WriteTest(std::string name = "");
virtual ~WriteTest();
};
#endif
@@ -1,207 +0,0 @@
/*
* Copyright 2026, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include "BStopWatchTest.h"
#include <cstring>
#include <unistd.h>
#include <StopWatch.h>
#include <cppunit/TestCaller.h>
#include <cppunit/TestSuite.h>
class BStopWatchTest : public BTestCase {
public:
BStopWatchTest(std::string name = "");
void NameWithNull_ReturnsEmptyString();
void NameWithValidString_ReturnsSetName();
void ElapsedTimeAfterDelay_Increases();
void ElapsedTimeWhenSuspended_DoesNotChange();
void LapWhenRunning_ReturnsIncreasingTime();
void LapWhenExceedsMax_StillReturnsValidTime();
void LapWhenSuspended_ReturnsZero();
void ResetAfterRunning_ClearsElapsedTime();
void ElapsedTimeAfterMultipleSuspendResume_OnlyCountsActivePeriods();
};
BStopWatchTest::BStopWatchTest(std::string name)
:BTestCase(name)
{
}
void
BStopWatchTest::NameWithNull_ReturnsEmptyString()
{
BStopWatch sw(NULL, true);
const char* name = sw.Name();
CPPUNIT_ASSERT(strcmp(name, "") == 0);
}
void
BStopWatchTest::NameWithValidString_ReturnsSetName()
{
BStopWatch sw("mywatch", true);
const char* name = sw.Name();
CPPUNIT_ASSERT(strcmp(name, "mywatch") == 0);
}
void
BStopWatchTest::ElapsedTimeAfterDelay_Increases()
{
BStopWatch sw("et", true);
bigtime_t t1 = sw.ElapsedTime();
CPPUNIT_ASSERT(t1 >= 0);
usleep(10000);
bigtime_t t2 = sw.ElapsedTime();
CPPUNIT_ASSERT(t2 > 0);
CPPUNIT_ASSERT(t2 > t1);
}
void
BStopWatchTest::ElapsedTimeWhenSuspended_DoesNotChange()
{
BStopWatch sw("sr", true);
usleep(5000);
sw.Suspend();
bigtime_t t1 = sw.ElapsedTime();
usleep(10000);
bigtime_t t2 = sw.ElapsedTime();
CPPUNIT_ASSERT_EQUAL(t1, t2);
sw.Resume();
usleep(5000);
bigtime_t t3 = sw.ElapsedTime();
CPPUNIT_ASSERT(t3 > t2);
}
void
BStopWatchTest::LapWhenRunning_ReturnsIncreasingTime()
{
BStopWatch sw("lap", true);
usleep(2000);
bigtime_t l1 = sw.Lap();
usleep(2000);
bigtime_t l2 = sw.Lap();
CPPUNIT_ASSERT(l2 > l1);
}
void
BStopWatchTest::LapWhenExceedsMax_StillReturnsValidTime()
{
BStopWatch sw("lapoverflow", true);
for (int i = 0; i < 12; i++)
sw.Lap();
CPPUNIT_ASSERT(sw.Lap() > 0);
}
void
BStopWatchTest::LapWhenSuspended_ReturnsZero()
{
BStopWatch sw("lap2", true);
sw.Suspend();
bigtime_t lapTime = sw.Lap();
CPPUNIT_ASSERT_EQUAL((bigtime_t)0, lapTime);
}
void
BStopWatchTest::ResetAfterRunning_ClearsElapsedTime()
{
BStopWatch sw("reset", true);
usleep(50000);
sw.Lap();
bigtime_t beforeReset = sw.ElapsedTime();
CPPUNIT_ASSERT(beforeReset >= 50000);
sw.Reset();
CPPUNIT_ASSERT(sw.ElapsedTime() < 5000);
}
void
BStopWatchTest::ElapsedTimeAfterMultipleSuspendResume_OnlyCountsActivePeriods()
{
BStopWatch sw("multi", true);
usleep(2000);
sw.Suspend();
usleep(2000);
sw.Resume();
usleep(2000);
sw.Suspend();
usleep(2000);
sw.Resume();
usleep(2000);
sw.Suspend();
bigtime_t elapsed = sw.ElapsedTime();
CPPUNIT_ASSERT(elapsed >= 6000);
CPPUNIT_ASSERT(elapsed < 7000);
}
CppUnit::Test*
BStopWatchTestSuite()
{
CppUnit::TestSuite* suite = new CppUnit::TestSuite("BStopWatch");
suite->addTest(new CppUnit::TestCaller<BStopWatchTest>(
"BStopWatchTest::NameWithNull_ReturnsEmptyString",
&BStopWatchTest::NameWithNull_ReturnsEmptyString));
suite->addTest(new CppUnit::TestCaller<BStopWatchTest>(
"BStopWatchTest::NameWithValidString_ReturnsSetName",
&BStopWatchTest::NameWithValidString_ReturnsSetName));
suite->addTest(new CppUnit::TestCaller<BStopWatchTest>(
"BStopWatchTest::ElapsedTimeAfterDelay_Increases",
&BStopWatchTest::ElapsedTimeAfterDelay_Increases));
suite->addTest(new CppUnit::TestCaller<BStopWatchTest>(
"BStopWatchTest::ElapsedTimeWhenSuspended_DoesNotChange",
&BStopWatchTest::ElapsedTimeWhenSuspended_DoesNotChange));
suite->addTest(new CppUnit::TestCaller<BStopWatchTest>(
"BStopWatchTest::LapWhenRunning_ReturnsIncreasingTime",
&BStopWatchTest::LapWhenRunning_ReturnsIncreasingTime));
suite->addTest(new CppUnit::TestCaller<BStopWatchTest>(
"BStopWatchTest::LapWhenExceedsMax_StillReturnsValidTime",
&BStopWatchTest::LapWhenExceedsMax_StillReturnsValidTime));
suite->addTest(new CppUnit::TestCaller<BStopWatchTest>(
"BStopWatchTest::LapWhenSuspended_ReturnsZero",
&BStopWatchTest::LapWhenSuspended_ReturnsZero));
suite->addTest(new CppUnit::TestCaller<BStopWatchTest>(
"BStopWatchTest::ResetAfterRunning_ClearsElapsedTime",
&BStopWatchTest::ResetAfterRunning_ClearsElapsedTime));
suite->addTest(new CppUnit::TestCaller<BStopWatchTest>(
"BStopWatchTest::ElapsedTimeAfterMultipleSuspendResume_OnlyCountsActivePeriods",
&BStopWatchTest::ElapsedTimeAfterMultipleSuspendResume_OnlyCountsActivePeriods));
return suite;
}

Some files were not shown because too many files have changed in this diff Show More