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:
@@ -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>
|
||||
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
+82
-53
@@ -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());
|
||||
+86
-74
@@ -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());
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
@@ -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(¬InListLow, Item::Compare);
|
||||
CPPUNIT_ASSERT(found == NULL);
|
||||
|
||||
found = (Item*)list.BinarySearch(¬InListHigh, 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(¬InListLow, Item::Compare);
|
||||
CPPUNIT_ASSERT_EQUAL(-1, searchIndex);
|
||||
|
||||
// notInListHigh
|
||||
searchIndex = list.BinarySearchIndex(¬InListHigh, 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(¬InList, 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());
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
@@ -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
Reference in New Issue
Block a user