mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
GEEKING
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
|
||||
|
||||
// This directive will define the main entry point
|
||||
#define BOOST_TEST_MODULE Base
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/parameterized_test.hpp>
|
||||
|
||||
#include "rbx/Debug.h"
|
||||
|
||||
#include "rbx/test/Base.UnitTest.Lib.h"
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
int BOOST_TEST_CALL_DECL
|
||||
main( int argc, char* argv[] )
|
||||
{
|
||||
char** filteredArgv = new char*[argc];
|
||||
int filteredArgc = 0;
|
||||
|
||||
for (int i = 0; i < argc; i++)
|
||||
if (!RBX::Test::BaseGlobalFixture::processArg(argv[i]))
|
||||
filteredArgv[filteredArgc++] = argv[i];
|
||||
|
||||
// prototype for user's unit test init function
|
||||
#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
|
||||
boost::unit_test::init_unit_test_func init_func = &init_unit_test;
|
||||
#else
|
||||
boost::unit_test::init_unit_test_func init_func = &init_unit_test_suite;
|
||||
#endif
|
||||
|
||||
int result = ::boost::unit_test::unit_test_main( init_func, filteredArgc, filteredArgv );
|
||||
delete [] filteredArgv;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
using namespace RBX::Test;
|
||||
|
||||
BOOST_GLOBAL_FIXTURE(BaseGlobalFixture);
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{E7993392-E347-400A-8742-8293564E1E8B}</ProjectGuid>
|
||||
<RootNamespace>BaseUnitTest</RootNamespace>
|
||||
<SccProjectName>Perforce Project</SccProjectName>
|
||||
<SccLocalPath>..</SccLocalPath>
|
||||
<SccProvider>MSSCCI:Perforce SCM</SccProvider>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v110_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="..\CustomBuildRules.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\PropertySheets\Common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\PropertySheets\Common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>bin\$(Configuration)\</OutDir>
|
||||
<IntDir>obj\$(Configuration)\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>bin\$(Configuration)\</OutDir>
|
||||
<IntDir>obj\$(Configuration)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(CONTRIB_PATH)\boost_1_56_0\include;..\Base.UnitTest.Lib\include;..\Base\include;..\TBB_4_1\include;..\Log\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>BOOST_THREAD_BUILD_LIB;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>..\TBB_4_1\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command />
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(CONTRIB_PATH)\boost_1_56_0\include;..\Base.UnitTest.Lib\include;..\Base\include;..\TBB_4_1\include;..\Log\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>BOOST_THREAD_BUILD_LIB;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>..\TBB_4_1\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/D "_SECURE_SCL=0" %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(CONTRIB_PATH)\boost_1_56_0\include;..\Base.UnitTest.Lib\include;..\Base\include;..\TBB_4_1\include;..\Log\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>BOOST_THREAD_BUILD_LIB;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>..\TBB_4_1\lib;..\boostlibs\bin\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<BaseAddress>0x00400000</BaseAddress>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command />
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/D "_SECURE_SCL=0" %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(CONTRIB_PATH)\boost_1_56_0\include;..\Base.UnitTest.Lib\include;..\Base\include;..\TBB_4_1\include;..\Log\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>BOOST_THREAD_BUILD_LIB;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>..\TBB_4_1\lib;..\boostlibs\bin\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<BaseAddress>0x00400000</BaseAddress>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="atomic.cpp" />
|
||||
<ClCompile Include="Base.UnitTest.cpp" />
|
||||
<ClCompile Include="CEvent.cpp" />
|
||||
<ClCompile Include="Crypt.cpp" />
|
||||
<ClCompile Include="DenseHashSet.cpp" />
|
||||
<ClCompile Include="intrusive_ptr.cpp" />
|
||||
<ClCompile Include="Log.cpp" />
|
||||
<ClCompile Include="make_shared.cpp" />
|
||||
<ClCompile Include="signals.cpp" />
|
||||
<ClCompile Include="spin_mutex_test.cpp" />
|
||||
<ClCompile Include="TaskScheduler.cpp" />
|
||||
<ClCompile Include="Time.cpp" />
|
||||
<ClCompile Include="trie.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Base.UnitTest.Lib\Base.UnitTest.Lib.vcxproj">
|
||||
<Project>{c5e89a79-bbc2-4ff3-80e1-69f5291f0c3c}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Base\Base.vcxproj">
|
||||
<Project>{3025c00a-7746-469b-a279-96127c72abee}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\boostlibs\boost.test.vcxproj">
|
||||
<Project>{55b54c4c-1951-4d6b-af5a-794214553001}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Log\Log.vcxproj">
|
||||
<Project>{9980f6c3-b64d-4775-8793-bb6dde31ce82}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\CustomBuildRules.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Libraries">
|
||||
<UniqueIdentifier>{ea58b07d-f626-4911-a363-1da9ee520da9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="atomic.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Base.UnitTest.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CEvent.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Crypt.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="intrusive_ptr.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Log.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="make_shared.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="signals.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="spin_mutex_test.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TaskScheduler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Time.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="trie.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DenseHashSet.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,76 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "rbx/test/TimeoutFixture.h"
|
||||
#include "RBX/CEvent.h"
|
||||
|
||||
|
||||
#ifdef RBX_PLATFORM_IOS
|
||||
#define TIMEOUT 60
|
||||
#else
|
||||
#define TIMEOUT 20
|
||||
#endif
|
||||
|
||||
using namespace boost;
|
||||
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(CEvent, RBX::Test::TimeoutFixture<TIMEOUT>)
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(CEventManual)
|
||||
{
|
||||
RBX::CEvent e(true);
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
e.Set();
|
||||
e.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
static void fCEventAuto(RBX::CEvent& e1, RBX::CEvent& e2)
|
||||
{
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
e1.Wait();
|
||||
e2.Set();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(CEventAuto)
|
||||
{
|
||||
RBX::CEvent e1(false);
|
||||
RBX::CEvent e2(false);
|
||||
boost::thread t(fCEventAuto, boost::ref(e1), boost::ref(e2));
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
e1.Set();
|
||||
e2.Wait();
|
||||
}
|
||||
t.join();
|
||||
}
|
||||
|
||||
void waitTest(double lower, double seconds, double upper)
|
||||
{
|
||||
RBX::CEvent e(true);
|
||||
RBX::Time start = RBX::Time::now<RBX::Time::Precise>();
|
||||
e.Wait(RBX::Time::Interval::from_seconds(seconds));
|
||||
RBX::Time::Interval waitTime = RBX::Time::now<RBX::Time::Precise>() - start;
|
||||
|
||||
#ifdef __APPLE__
|
||||
BOOST_WARN_GT(waitTime.seconds(), lower);
|
||||
BOOST_WARN_LT(waitTime.seconds(), upper);
|
||||
#else
|
||||
BOOST_CHECK_GT(waitTime.seconds(), lower);
|
||||
BOOST_CHECK_LT(waitTime.seconds(), upper);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(CEventTimeout)
|
||||
{
|
||||
waitTest(0.5, 1, 1.5);
|
||||
waitTest(1, 2, 3);
|
||||
waitTest(2, 3, 4);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "rbx/crypt.h"
|
||||
|
||||
using namespace boost;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Crypt)
|
||||
|
||||
const char* message = "Hello World!";
|
||||
const char* signatureBase64 = "ZLrv3Sy5zh08/+tec0tw2dMJ1JkhX/TcItuo/IuYPkP3muftzYEU3mt+uU9236Hdh2RQlUIw3me/hI06aj9KVAbS8dHSzHbF6GpkhhmwmiLW4v8XfSFb//XujR4nEadWi21mzWTVDEySJA66uotV63r3jvYmVHC+o35dBN0h5Jw=";
|
||||
|
||||
#ifndef RBX_PLATFORM_IOS
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PositiveTest)
|
||||
{
|
||||
RBX::Crypt crypt;
|
||||
BOOST_CHECK_NO_THROW(crypt.verifySignatureBase64(message, signatureBase64));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(NegativeTest)
|
||||
{
|
||||
RBX::Crypt crypt;
|
||||
BOOST_CHECK_THROW(crypt.verifySignatureBase64("Tampered message", signatureBase64), std::exception);
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
#include "rbx/DenseHash.h"
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(DenseHashSet)
|
||||
|
||||
template <typename Set> void verifyContentsRange(const Set& set, int begin, int end)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(set.size(), end - begin);
|
||||
|
||||
std::vector<int> data;
|
||||
|
||||
for (typename Set::const_iterator it = set.begin(); it != set.end(); ++it)
|
||||
data.push_back(*it);
|
||||
|
||||
BOOST_CHECK_EQUAL(data.size(), end - begin);
|
||||
|
||||
std::sort(data.begin(), data.end());
|
||||
|
||||
for (size_t i = 0; i < data.size(); ++i)
|
||||
BOOST_CHECK_EQUAL(data[i], begin + i);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SimpleForward)
|
||||
{
|
||||
RBX::DenseHashSet<int> set(-1);
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
set.insert(i);
|
||||
|
||||
verifyContentsRange(set, 0, 5);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SimpleBackward)
|
||||
{
|
||||
RBX::DenseHashSet<int> set(-1);
|
||||
|
||||
for (int i = 4; i >= 0; --i)
|
||||
set.insert(i);
|
||||
|
||||
verifyContentsRange(set, 0, 5);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SimpleDuplicate)
|
||||
{
|
||||
RBX::DenseHashSet<int> set(-1);
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
set.insert(i);
|
||||
|
||||
for (int i = 4; i >= 0; --i)
|
||||
set.insert(i);
|
||||
|
||||
verifyContentsRange(set, 0, 5);
|
||||
}
|
||||
|
||||
struct HasherOne
|
||||
{
|
||||
int operator()(int value) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE(LargeBadHashFunction)
|
||||
{
|
||||
RBX::DenseHashSet<int, HasherOne> set(-1);
|
||||
|
||||
for (int i = 0; i < 512; ++i)
|
||||
set.insert(i);
|
||||
|
||||
verifyContentsRange(set, 0, 512);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ContainsSimple)
|
||||
{
|
||||
RBX::DenseHashSet<int> set(0);
|
||||
|
||||
BOOST_CHECK_EQUAL(set.contains(1), false);
|
||||
BOOST_CHECK_EQUAL(set.contains(2), false);
|
||||
|
||||
set.insert(1);
|
||||
|
||||
BOOST_CHECK_EQUAL(set.contains(1), true);
|
||||
BOOST_CHECK_EQUAL(set.contains(2), false);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ContainsSieve)
|
||||
{
|
||||
RBX::DenseHashSet<int> sieve(0);
|
||||
|
||||
for (int i = 2; i < 100; ++i)
|
||||
{
|
||||
if (!sieve.contains(i))
|
||||
{
|
||||
for (int k = 2; k * i < 100; ++k)
|
||||
sieve.insert(k * i);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(sieve.contains(81), true);
|
||||
BOOST_CHECK_EQUAL(sieve.contains(97), false);
|
||||
BOOST_CHECK_EQUAL(sieve.contains(98), true);
|
||||
BOOST_CHECK_EQUAL(sieve.contains(99), true);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SizeEmpty)
|
||||
{
|
||||
RBX::DenseHashSet<int> set(0);
|
||||
|
||||
BOOST_CHECK_EQUAL(set.size(), 0);
|
||||
BOOST_CHECK_EQUAL(set.empty(), true);
|
||||
|
||||
set.insert(5);
|
||||
|
||||
BOOST_CHECK_EQUAL(set.size(), 1);
|
||||
BOOST_CHECK_EQUAL(set.empty(), false);
|
||||
|
||||
BOOST_CHECK_EQUAL(*set.begin(), 5);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SizeBuckets)
|
||||
{
|
||||
RBX::DenseHashSet<int> set(-1);
|
||||
|
||||
BOOST_CHECK_EQUAL(set.size(), 0);
|
||||
BOOST_CHECK_EQUAL(set.bucket_count(), 0);
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
set.insert(i*i);
|
||||
|
||||
for (int i = 99; i >= 0; --i)
|
||||
set.insert(i*i);
|
||||
|
||||
BOOST_CHECK_EQUAL(set.size(), 100);
|
||||
BOOST_CHECK_EQUAL(set.bucket_count(), 256);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(BucketsStartingAt1)
|
||||
{
|
||||
RBX::DenseHashSet<int> set(-1, 1);
|
||||
|
||||
BOOST_CHECK_EQUAL(set.size(), 0);
|
||||
BOOST_CHECK_EQUAL(set.bucket_count(), 1);
|
||||
|
||||
set.insert(1);
|
||||
|
||||
BOOST_CHECK_EQUAL(set.size(), 1);
|
||||
BOOST_CHECK_EQUAL(set.bucket_count(), 2);
|
||||
|
||||
set.insert(4);
|
||||
|
||||
BOOST_CHECK_EQUAL(set.size(), 2);
|
||||
BOOST_CHECK_EQUAL(set.bucket_count(), 4);
|
||||
|
||||
set.insert(9);
|
||||
|
||||
BOOST_CHECK_EQUAL(set.size(), 3);
|
||||
BOOST_CHECK_EQUAL(set.bucket_count(), 4);
|
||||
|
||||
set.insert(16);
|
||||
|
||||
BOOST_CHECK_EQUAL(set.size(), 4);
|
||||
BOOST_CHECK_EQUAL(set.bucket_count(), 8);
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
set.insert(i * i);
|
||||
|
||||
BOOST_CHECK_EQUAL(set.size(), 100);
|
||||
BOOST_CHECK_EQUAL(set.bucket_count(), 256);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(IteratorOps)
|
||||
{
|
||||
RBX::DenseHashSet<int> set(-1);
|
||||
|
||||
set.insert(1);
|
||||
set.insert(2);
|
||||
|
||||
RBX::DenseHashSet<int>::const_iterator it1 = set.begin();
|
||||
|
||||
RBX::DenseHashSet<int>::const_iterator it2 = it1;
|
||||
RBX::DenseHashSet<int>::const_iterator it3 = ++it2;
|
||||
|
||||
RBX::DenseHashSet<int>::const_iterator it4 = it1;
|
||||
RBX::DenseHashSet<int>::const_iterator it5 = it4++;
|
||||
|
||||
BOOST_CHECK_EQUAL(it1 == set.begin(), true);
|
||||
BOOST_CHECK_EQUAL(it1 != set.begin(), false);
|
||||
BOOST_CHECK_EQUAL(it1 == set.end(), false);
|
||||
BOOST_CHECK_EQUAL(it1 != set.end(), true);
|
||||
|
||||
BOOST_CHECK(it2 == it4);
|
||||
BOOST_CHECK(it2 != it1);
|
||||
BOOST_CHECK(it2 != set.end());
|
||||
|
||||
BOOST_CHECK(it3 == it2);
|
||||
BOOST_CHECK(it5 == it1);
|
||||
|
||||
BOOST_CHECK(it1 == it5);
|
||||
|
||||
BOOST_CHECK((*it1 == 1 && *it2 == 2) || (*it1 == 2 && *it1 == 1));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -0,0 +1,179 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "FastLog.h"
|
||||
#include "rbx/rbxTime.h"
|
||||
|
||||
using namespace boost;
|
||||
|
||||
LOGGROUP(UnitTestOn)
|
||||
LOGGROUP(UnitTestOff)
|
||||
|
||||
LOGVARIABLE(UnitTestOn, 1)
|
||||
LOGVARIABLE(UnitTestOff, 0)
|
||||
|
||||
DYNAMIC_FASTFLAGVARIABLE(DebugUnitDynamicFlag, true)
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(FastLog)
|
||||
|
||||
static int i = 23;
|
||||
static int increment() { return ++i; }
|
||||
|
||||
BOOST_AUTO_TEST_CASE(TrailingSemicolon)
|
||||
{
|
||||
if (false)
|
||||
FASTLOG(FLog::UnitTestOn, "Just Message");
|
||||
else
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Conditionals)
|
||||
{
|
||||
int i = 2;
|
||||
if (false)
|
||||
FASTLOG1(FLog::UnitTestOff, "Just Message %d", increment());
|
||||
else if (true)
|
||||
i = 4;
|
||||
|
||||
BOOST_CHECK_EQUAL(i, 4);
|
||||
|
||||
// If this test fails, then the macro was not written properly because
|
||||
// it exposes a partial if-then block. (One more reason MACROS are worse than templates :)
|
||||
//
|
||||
// Here is the incorrect implementation:
|
||||
// #define FASTLOG1(group,level,message,arg1) if(...) RBX::FastLog(...)
|
||||
//
|
||||
// Here is a correct implementation:
|
||||
// #define FASTLOG1(group,level,message,arg1) do { if(...) RBX::FastLog(...); } while (0)
|
||||
//
|
||||
// The do {} while (0) clause is one way to wrap the macro into a self-contained statement
|
||||
// IMPORTANT Notice that there is NO ";" at the end of the block.
|
||||
// See http://stackoverflow.com/questions/1067226/c-multi-line-macro-do-while0-vs-scope-block
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(LazyEval)
|
||||
{
|
||||
i = 3;
|
||||
FASTLOG1(FLog::UnitTestOff, "Just Message %d", increment());
|
||||
BOOST_CHECK_EQUAL(i, 3);
|
||||
|
||||
i = 13;
|
||||
FASTLOG1(FLog::Warning, "Warning %d", increment());
|
||||
BOOST_CHECK_EQUAL(i, 14);
|
||||
|
||||
i = 23;
|
||||
FASTLOG1(FLog::Error, "Just Message %d", increment());
|
||||
BOOST_CHECK_EQUAL(i, 24);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(BasicLog)
|
||||
{
|
||||
RBX::Time start = RBX::Time::now<RBX::Time::Multimedia>();
|
||||
|
||||
std::string nullString = "", shortString = "aaaaa", longString = "very very long string";
|
||||
for(int i = 0; i < LOG_HISTORY; i++)
|
||||
{
|
||||
FASTLOG(FLog::UnitTestOn, "Just Message");
|
||||
FASTLOG1(FLog::UnitTestOn, "Message with argument %u", 1);
|
||||
FASTLOG3(FLog::UnitTestOn, "Message with pointer %p, number %u and %u", this, 3, 2);
|
||||
FASTLOGS(FLog::UnitTestOn, "String message - %s", "");
|
||||
FASTLOGS(FLog::UnitTestOn, "String message - %s", "AAAAA");
|
||||
FASTLOGS(FLog::UnitTestOn, "Large string message - %s", "01234567890123456789");
|
||||
|
||||
FASTLOG1F(FLog::UnitTestOn, "Message with argument %f", 10.0f);
|
||||
FASTLOG3F(FLog::UnitTestOn, "Message with argument %f %f %f", 10.0f, 5.0f, -1.0f);
|
||||
|
||||
FASTLOG(FLog::UnitTestOn, "Log");
|
||||
FASTLOG(FLog::UnitTestOn, "One more");
|
||||
|
||||
FASTLOG(FLog::UnitTestOff, "Off");
|
||||
FASTLOG(FLog::UnitTestOff, "Off, but on");
|
||||
|
||||
FASTLOGS(FLog::UnitTestOn, "Null string message - %s", nullString);
|
||||
FASTLOGS(FLog::UnitTestOn, "Short string message - %s", shortString);
|
||||
FASTLOGS(FLog::UnitTestOn, "Long string message - %s", longString);
|
||||
}
|
||||
|
||||
RBX::Time finish = RBX::Time::now<RBX::Time::Multimedia>();
|
||||
FASTLOG1F(FLog::UnitTestOn, "Logging took %f seconds", (float)(finish - start).seconds());
|
||||
}
|
||||
|
||||
FASTFLAGVARIABLE(TestFastFlag, false)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(FastFlags)
|
||||
{
|
||||
// We can't do the following test because the --fflags= arg might have overriden it
|
||||
//BOOST_CHECK_EQUAL(FFlag::TestFastFlag, false);
|
||||
FLog::SetValue("TestFastFlag", "True", FASTVARTYPE_STATIC);
|
||||
BOOST_CHECK_EQUAL(FFlag::TestFastFlag, true);
|
||||
FLog::SetValue("TestFastFlag", "False", FASTVARTYPE_STATIC);
|
||||
BOOST_CHECK_EQUAL(FFlag::TestFastFlag, false);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SettingUnknownGroups)
|
||||
{
|
||||
FLog::SetValue("UnknownGroup", "1", FASTVARTYPE_STATIC);
|
||||
FLog::SetValue("UnknownFlag", "true", FASTVARTYPE_STATIC);
|
||||
{
|
||||
FLog::Channel UnknownGroup = 0;
|
||||
FLog::RegisterLogGroup("UnknownGroup", &UnknownGroup);
|
||||
|
||||
bool UnknownFlag = 0;
|
||||
FLog::RegisterFlag("UnknownFlag", &UnknownFlag);
|
||||
|
||||
BOOST_CHECK_EQUAL(UnknownGroup, 1);
|
||||
BOOST_CHECK_EQUAL(UnknownFlag, true);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DynamicVariables)
|
||||
{
|
||||
FLog::SetValue("DebugUnitDynamicFlag", "false", FASTVARTYPE_STATIC);
|
||||
BOOST_CHECK_EQUAL(DFFlag::DebugUnitDynamicFlag, true);
|
||||
FLog::SetValue("DebugUnitDynamicFlag", "false", FASTVARTYPE_DYNAMIC);
|
||||
BOOST_CHECK_EQUAL(DFFlag::DebugUnitDynamicFlag, false);
|
||||
}
|
||||
|
||||
FASTINTVARIABLE(TestFastInt, 3)
|
||||
BOOST_AUTO_TEST_CASE(FastInts)
|
||||
{
|
||||
FLog::SetValue("TestFastInt", "2", FASTVARTYPE_STATIC);
|
||||
BOOST_CHECK_EQUAL(FInt::TestFastInt, 2);
|
||||
}
|
||||
|
||||
SYNCHRONIZED_FASTFLAGVARIABLE(TestSynchronizedFlag, false);
|
||||
BOOST_AUTO_TEST_CASE(SynchronizedFlagVariables)
|
||||
{
|
||||
FLog::SetValue("TestSynchronizedFlag", "true", FASTVARTYPE_STATIC);
|
||||
BOOST_CHECK_EQUAL(SFFlag::TestSynchronizedFlag, false);
|
||||
|
||||
FLog::SetValue("TestSynchronizedFlag", "true", FASTVARTYPE_SYNC);
|
||||
BOOST_CHECK_EQUAL(SFFlag::TestSynchronizedFlag, true);
|
||||
BOOST_CHECK_EQUAL(*SFFlag::TestSynchronizedFlagIsSync, true);
|
||||
|
||||
FLog::ResetSynchronizedVariablesState();
|
||||
BOOST_CHECK_EQUAL(*SFFlag::TestSynchronizedFlagIsSync, false);
|
||||
|
||||
FLog::SetValueFromServer("TestSynchronizedFlag", "true");
|
||||
BOOST_CHECK_EQUAL(SFFlag::TestSynchronizedFlag, true);
|
||||
BOOST_CHECK_EQUAL(*SFFlag::TestSynchronizedFlagIsSync, true);
|
||||
}
|
||||
|
||||
SYNCHRONIZED_FASTINTVARIABLE(UnitSynchronizedInt, 0);
|
||||
BOOST_AUTO_TEST_CASE(SynchronizedIntVariables)
|
||||
{
|
||||
FLog::SetValue("UnitSynchronizedInt", "1", FASTVARTYPE_STATIC);
|
||||
BOOST_CHECK_EQUAL(SFInt::UnitSynchronizedInt, 0);
|
||||
|
||||
FLog::SetValue("UnitSynchronizedInt", "1", FASTVARTYPE_SYNC);
|
||||
BOOST_CHECK_EQUAL(SFInt::UnitSynchronizedInt, 1);
|
||||
|
||||
// flag state was reset in the previous test, so IsSynce should be false here
|
||||
BOOST_CHECK_EQUAL(*SFInt::UnitSynchronizedIntIsSync, false);
|
||||
|
||||
FLog::SetValueFromServer("UnitSynchronizedInt", "2");
|
||||
BOOST_CHECK_EQUAL(SFInt::UnitSynchronizedInt, 2);
|
||||
BOOST_CHECK_EQUAL(*SFInt::UnitSynchronizedIntIsSync, true);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -0,0 +1,62 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "rbx/TaskScheduler.h"
|
||||
#include "rbx/TaskScheduler.Job.h"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(TaskScheduler)
|
||||
|
||||
class ParallelTestJob : public RBX::TaskScheduler::Job
|
||||
{
|
||||
public:
|
||||
int maxConcurrency;
|
||||
ParallelTestJob()
|
||||
:Job("ParallelTestJob", shared_ptr<RBX::TaskScheduler::Arbiter>())
|
||||
{
|
||||
maxConcurrency = 0;
|
||||
}
|
||||
RBX::Time::Interval sleepTime(const Stats& stats)
|
||||
{
|
||||
return computeStandardSleepTime(stats, 10);
|
||||
}
|
||||
|
||||
virtual Job::Error error(const Stats& stats)
|
||||
{
|
||||
Job::Error result = computeStandardErrorCyclicExecutiveSleeping(stats, 10);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual RBX::TaskScheduler::StepResult step(const Stats& stats)
|
||||
{
|
||||
RBX::Time::Interval(0.1).sleep();
|
||||
if (this->allotedConcurrency > maxConcurrency)
|
||||
maxConcurrency = this->allotedConcurrency;
|
||||
return RBX::TaskScheduler::Stepped;
|
||||
}
|
||||
virtual int getDesiredConcurrencyCount() const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
protected:
|
||||
/*implement*/ double getPriorityFactor() { return 1.0; }
|
||||
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ParallelTest)
|
||||
{
|
||||
shared_ptr<ParallelTestJob> job(new ParallelTestJob());
|
||||
|
||||
RBX::TaskScheduler::singleton().add(job);
|
||||
|
||||
for (int i = 0; i < 20; ++i)
|
||||
{
|
||||
RBX::Time::Interval(1).sleep();
|
||||
if (job->maxConcurrency > 1)
|
||||
break;
|
||||
}
|
||||
BOOST_CHECK_GT(job->maxConcurrency, 1);
|
||||
|
||||
RBX::TaskScheduler::singleton().removeBlocking(job);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "rbx/rbxtime.h"
|
||||
#include "rbxformat.h"
|
||||
|
||||
using namespace boost;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Format)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SmallString)
|
||||
{
|
||||
std::string s;
|
||||
for (int i=0; i<125; ++i)
|
||||
s += "x";
|
||||
BOOST_CHECK( RBX::format("%s", s.c_str()) == s);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(BigString)
|
||||
{
|
||||
std::string s;
|
||||
for (int i=0; i<500; ++i)
|
||||
s += "x";
|
||||
BOOST_CHECK( RBX::format("%s", s.c_str()) == s);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Time)
|
||||
|
||||
template <RBX::Time::SampleMethod T>
|
||||
static void test()
|
||||
{
|
||||
BOOST_CHECK(true);
|
||||
for (int i=0; i<1e7; ++i)
|
||||
RBX::Time::now<T>();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Fast)
|
||||
{
|
||||
test<RBX::Time::Fast>();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Multimedia)
|
||||
{
|
||||
test<RBX::Time::Multimedia>();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Precise)
|
||||
{
|
||||
test<RBX::Time::Precise>();
|
||||
}
|
||||
|
||||
template <RBX::Time::SampleMethod T>
|
||||
static void testAccuracy()
|
||||
{
|
||||
RBX::Time was = RBX::Time::now<T>();
|
||||
#ifdef _DEBUG
|
||||
for (int i=0; i<1e4; ++i)
|
||||
#else
|
||||
for (int i=0; i<1e6; ++i)
|
||||
#endif
|
||||
{
|
||||
RBX::Time now = RBX::Time::now<T>();
|
||||
double sec = (now - was).seconds();
|
||||
BOOST_CHECK_GE(sec, 0.0);
|
||||
//BOOST_CHECK_LE(sec, 0.0011);
|
||||
was = now;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(FastAccuracy)
|
||||
{
|
||||
testAccuracy<RBX::Time::Fast>();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(MultimediaAccuracy)
|
||||
{
|
||||
testAccuracy<RBX::Time::Multimedia>();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PreciseAccuracy)
|
||||
{
|
||||
testAccuracy<RBX::Time::Precise>();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "concurrent.h"
|
||||
|
||||
#include "rbx/atomic.h"
|
||||
#include "rbx/boost.hpp"
|
||||
|
||||
namespace AtomicTest
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Atomic)
|
||||
|
||||
template<class V, class UV>
|
||||
static void test()
|
||||
{
|
||||
#ifndef RBX_PLATFORM_IOS
|
||||
{
|
||||
rbx::atomic<V> v;
|
||||
v = 0;
|
||||
BOOST_CHECK_EQUAL(++v, (V)1);
|
||||
BOOST_CHECK_EQUAL(--v, (V)0);
|
||||
BOOST_CHECK_EQUAL(--v, -(V)1);
|
||||
BOOST_CHECK_EQUAL(++v, (V)0);
|
||||
/* // we dont test unsigned until further notice
|
||||
rbx::atomic<UV> uv;
|
||||
uv = 0;
|
||||
BOOST_CHECK_EQUAL(--uv, (UV)~0);
|
||||
BOOST_CHECK_EQUAL(++uv, (UV)0);
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
rbx::atomic<V> v;
|
||||
BOOST_CHECK_EQUAL(++v, (V)1);
|
||||
BOOST_CHECK_EQUAL(--v, (V)0);
|
||||
BOOST_CHECK_EQUAL(--v, -(V)1);
|
||||
BOOST_CHECK_EQUAL(++v, (V)0);
|
||||
|
||||
#ifndef RBX_PLATFORM_IOS
|
||||
/* // we dont test unsigned until further notice
|
||||
rbx::atomic<UV> uv;
|
||||
BOOST_CHECK_EQUAL(--uv, (UV)~0);
|
||||
BOOST_CHECK_EQUAL(++uv, (UV)0);
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Int)
|
||||
{
|
||||
test<int, unsigned int>();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Long)
|
||||
{
|
||||
test<long, unsigned long>();
|
||||
}
|
||||
|
||||
// may need longlong test when we finally implement it
|
||||
|
||||
template<typename T>
|
||||
struct TestIncrement
|
||||
{
|
||||
TestIncrement()
|
||||
{
|
||||
const int threads = 8;
|
||||
const int iterations = 1000000;
|
||||
rbx::atomic<T> state;
|
||||
|
||||
util::ConcurrentLoops<Incrementer>::run(Incrementer(state), iterations, threads);
|
||||
BOOST_CHECK_EQUAL(state, threads * iterations);
|
||||
|
||||
util::ConcurrentLoops<Decrementer>::run(Decrementer(state), iterations / 2, threads);
|
||||
BOOST_CHECK_EQUAL(state, threads * iterations / 2);
|
||||
|
||||
util::ConcurrentLoops<Decrementer>::run(Decrementer(state), iterations / 2, threads);
|
||||
BOOST_CHECK_EQUAL(state, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
struct Incrementer
|
||||
{
|
||||
int operator()(int)
|
||||
{
|
||||
++state_;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Incrementer(rbx::atomic<T> &state) : state_(state) {}
|
||||
|
||||
private:
|
||||
rbx::atomic<T> &state_;
|
||||
};
|
||||
|
||||
struct Decrementer
|
||||
{
|
||||
int operator()(int)
|
||||
{
|
||||
--state_;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Decrementer(rbx::atomic<T> &state) : state_(state) {}
|
||||
|
||||
private:
|
||||
rbx::atomic<T> &state_;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TestCASFalsePositive
|
||||
{
|
||||
TestCASFalsePositive()
|
||||
{
|
||||
const int threads = 8;
|
||||
const int iterations = 1000000;
|
||||
rbx::atomic<T> state;
|
||||
|
||||
BOOST_CHECK_EQUAL(state, 0);
|
||||
BOOST_CHECK_EQUAL(util::ConcurrentLoops<StateGrabber>::run(StateGrabber(state), iterations, threads), 0);
|
||||
BOOST_CHECK_EQUAL(state, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
struct StateGrabber
|
||||
{
|
||||
int operator()(int index)
|
||||
{
|
||||
const T target = index + 1;
|
||||
if (0 == state_.compare_and_swap(target, 0))
|
||||
{
|
||||
if (state_.compare_and_swap(0, target) != target)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
StateGrabber(rbx::atomic<T> &state) : state_(state) {}
|
||||
|
||||
private:
|
||||
rbx::atomic<T> &state_;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T, int NThreads, int NIterations>
|
||||
struct TestSwap
|
||||
{
|
||||
TestSwap()
|
||||
{
|
||||
rbx::atomic<T> histogram[NThreads + 1];
|
||||
rbx::atomic<T> state;
|
||||
|
||||
BOOST_CHECK_EQUAL(state, 0);
|
||||
for (auto &h : histogram) // curly braces are important here due to compiler bug in visual studio < 2015
|
||||
{
|
||||
BOOST_CHECK_EQUAL(h, 0);
|
||||
}
|
||||
|
||||
++histogram[0];
|
||||
BOOST_CHECK_EQUAL(histogram[0], 1);
|
||||
|
||||
BOOST_CHECK_EQUAL(util::ConcurrentLoops<StateSwapper>::run(StateSwapper(state, histogram), NIterations, NThreads), 0);
|
||||
|
||||
BOOST_CHECK_LE(state, NThreads);
|
||||
|
||||
--histogram[state];
|
||||
|
||||
for (auto &h : histogram) // curly braces are important here due to compiler bug in visual studio < 2015
|
||||
{
|
||||
BOOST_CHECK_EQUAL(h, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct StateSwapper
|
||||
{
|
||||
int operator()(int index)
|
||||
{
|
||||
const T target = index + 1;
|
||||
const T old = state_.swap(target);
|
||||
|
||||
if (old > NThreads)
|
||||
return 1;
|
||||
|
||||
++histogram_[target];
|
||||
--histogram_[old];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
StateSwapper(rbx::atomic<T> &state, rbx::atomic<T> *histogram)
|
||||
: state_(state)
|
||||
, histogram_(histogram) {}
|
||||
|
||||
private:
|
||||
rbx::atomic<T> &state_;
|
||||
rbx::atomic<T> *histogram_;
|
||||
};
|
||||
};
|
||||
|
||||
// The tests below are independent tests -- only atomicity relative to
|
||||
// the same kind of operation performed in another threads is tested.
|
||||
|
||||
// Currenly there are no tests for cas vs. inc/dec vs. swap() atomicity.
|
||||
// TODO
|
||||
|
||||
BOOST_AUTO_TEST_CASE(increment)
|
||||
{
|
||||
TestIncrement<int> test_int;
|
||||
TestIncrement<long> test_long;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cas_false_positive)
|
||||
{
|
||||
TestCASFalsePositive<int> test_int;
|
||||
TestCASFalsePositive<long> test_long;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(swap)
|
||||
{
|
||||
TestSwap<int, 8, 1000000> test_int;
|
||||
TestSwap<long, 8, 1000000> test_long;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END() // Atomic
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
namespace util
|
||||
{
|
||||
template <typename F>
|
||||
struct ConcurrentLoops
|
||||
{
|
||||
static int run(F f, int iterations, int num_threads)
|
||||
{
|
||||
int result = 0;
|
||||
std::vector<std::pair<boost::thread*, int> > threads(num_threads);
|
||||
int index = 0;
|
||||
for (auto &it : threads)
|
||||
{
|
||||
it.first = new boost::thread(threadFunc, f, index++, iterations, it.second);
|
||||
}
|
||||
|
||||
for (auto &it : threads)
|
||||
{
|
||||
it.first->join();
|
||||
delete it.first;
|
||||
it.first = 0;
|
||||
if (it.second)
|
||||
result = it.second;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
static void threadFunc(F &f, int index, int iterations, int &result)
|
||||
{
|
||||
for (int i = 0; i < iterations; ++i)
|
||||
{
|
||||
result = f(index);
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}; // struct ConcurrentLoops
|
||||
|
||||
} // namespace utils
|
||||
@@ -0,0 +1,304 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "boost/shared_ptr.hpp"
|
||||
#include "boost/weak_ptr.hpp"
|
||||
|
||||
#include "rbx/intrusive_ptr_target.h"
|
||||
#include "rbx/intrusive_weak_ptr.h"
|
||||
|
||||
|
||||
namespace IntrusiveTest
|
||||
{
|
||||
|
||||
class CountedBase : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
std::string foo;
|
||||
static int count;
|
||||
int id;
|
||||
CountedBase()
|
||||
{
|
||||
count++;
|
||||
static int guid = 0;
|
||||
id = ++guid;
|
||||
}
|
||||
~CountedBase()
|
||||
{
|
||||
foo = "bye base!";
|
||||
count--;
|
||||
}
|
||||
};
|
||||
int CountedBase::count = 0;
|
||||
|
||||
class Counted
|
||||
: public rbx::intrusive_ptr_target<Counted>
|
||||
, public CountedBase
|
||||
{
|
||||
public:
|
||||
Counted() {
|
||||
}
|
||||
virtual ~Counted()
|
||||
{
|
||||
foo = "bye!";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class CountedChild : public Counted
|
||||
{
|
||||
public:
|
||||
~CountedChild()
|
||||
{
|
||||
foo = "bye child!";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class QuickCounted
|
||||
: public rbx::quick_intrusive_ptr_target<QuickCounted>
|
||||
, public CountedBase
|
||||
{
|
||||
public:
|
||||
QuickCounted() {
|
||||
}
|
||||
virtual ~QuickCounted()
|
||||
{
|
||||
foo = "bye!";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class QuickCountedChild : public QuickCounted
|
||||
{
|
||||
public:
|
||||
~QuickCountedChild()
|
||||
{
|
||||
foo = "bye child!";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CountedFixture
|
||||
{
|
||||
int count;
|
||||
public:
|
||||
CountedFixture() {
|
||||
count = CountedBase::count;
|
||||
}
|
||||
~CountedFixture() {
|
||||
BOOST_CHECK_EQUAL(CountedBase::count, count);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(intrusive_ptr, CountedFixture)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Test)
|
||||
{
|
||||
boost::intrusive_ptr<Counted> p1 = new CountedChild();
|
||||
|
||||
BOOST_CHECK_EQUAL(1, Counted::count);
|
||||
//BOOST_CHECK_EQUAL(1, p1.use_count());
|
||||
|
||||
{
|
||||
boost::intrusive_ptr<Counted> p2 = p1;
|
||||
boost::intrusive_ptr<Counted> p3(p1);
|
||||
|
||||
//BOOST_CHECK_EQUAL(3, p1.use_count());
|
||||
//BOOST_CHECK_EQUAL(3, p2.use_count());
|
||||
//BOOST_CHECK_EQUAL(3, p3.use_count());
|
||||
|
||||
p3.reset();
|
||||
|
||||
BOOST_CHECK_EQUAL(1, Counted::count);
|
||||
//BOOST_CHECK_EQUAL(2, p1.use_count());
|
||||
//BOOST_CHECK_EQUAL(2, p2.use_count());
|
||||
//BOOST_CHECK_EQUAL(0, p3.use_count());
|
||||
}
|
||||
//BOOST_CHECK_EQUAL(1, p1.use_count());
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Operators)
|
||||
{
|
||||
boost::intrusive_ptr<Counted> p1 = new CountedChild();
|
||||
BOOST_CHECK_EQUAL(1, Counted::count);
|
||||
|
||||
Counted* c1 = p1.get();
|
||||
BOOST_CHECK_EQUAL(1, Counted::count);
|
||||
|
||||
Counted& c2 = *p1;
|
||||
BOOST_CHECK_EQUAL(1, Counted::count);
|
||||
|
||||
BOOST_CHECK_EQUAL(c1, &c2);
|
||||
BOOST_CHECK_EQUAL(c2.id, p1->id);
|
||||
BOOST_CHECK_EQUAL(c2.id, (*p1).id);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define ccc 1
|
||||
#else
|
||||
#define ccc 10000000
|
||||
#endif
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Perf_Intrusive)
|
||||
{
|
||||
boost::intrusive_ptr<Counted> p1 = new CountedChild();
|
||||
boost::intrusive_ptr<Counted> w;
|
||||
for (int i = 0; i < ccc; ++i)
|
||||
{
|
||||
boost::intrusive_ptr<Counted> w1 = p1;
|
||||
w = p1;
|
||||
w.reset();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Perf_Quick)
|
||||
{
|
||||
boost::intrusive_ptr<QuickCounted> p1 = new QuickCountedChild();
|
||||
boost::intrusive_ptr<QuickCounted> w;
|
||||
for (int i = 0; i < ccc; ++i)
|
||||
{
|
||||
boost::intrusive_ptr<QuickCounted> w1 = p1;
|
||||
w = p1;
|
||||
w.reset();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Perf_Shared)
|
||||
{
|
||||
boost::shared_ptr<Counted> p1(new CountedChild());
|
||||
boost::shared_ptr<Counted> w;
|
||||
for (int i = 0; i < ccc; ++i)
|
||||
{
|
||||
boost::shared_ptr<Counted> w1 = p1;
|
||||
w = p1;
|
||||
w.reset();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PerfDelete_Intrusive)
|
||||
{
|
||||
for (int i = 0; i <= ccc/10; ++i)
|
||||
{
|
||||
boost::intrusive_ptr<Counted> p1 = new CountedChild();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PerfDelete_Quick)
|
||||
{
|
||||
for (int i = 0; i <= ccc/10; ++i)
|
||||
{
|
||||
boost::intrusive_ptr<QuickCounted> p1 = new QuickCountedChild();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PerfDelete_Shared)
|
||||
{
|
||||
for (int i = 0; i <= ccc/10; ++i)
|
||||
{
|
||||
boost::shared_ptr<Counted> p1(new CountedChild());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PerfWeak_Intrusive)
|
||||
{
|
||||
boost::intrusive_ptr<Counted> p1 = new CountedChild();
|
||||
rbx::intrusive_weak_ptr<Counted> w;
|
||||
for (int i = 0; i < ccc; ++i)
|
||||
{
|
||||
rbx::intrusive_weak_ptr<Counted> w1 = p1;
|
||||
w = p1;
|
||||
w.reset();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PerfWeak_Shared)
|
||||
{
|
||||
boost::shared_ptr<Counted> p1(new CountedChild());
|
||||
boost::weak_ptr<Counted> w;
|
||||
for (int i = 0; i < ccc; ++i)
|
||||
{
|
||||
boost::weak_ptr<Counted> w1 = p1;
|
||||
w = p1;
|
||||
w.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WeakTest)
|
||||
{
|
||||
boost::intrusive_ptr<CountedChild> p1 = new CountedChild();
|
||||
|
||||
BOOST_CHECK_EQUAL(1, Counted::count);
|
||||
//BOOST_CHECK_EQUAL(1, p1.use_count());
|
||||
|
||||
rbx::intrusive_weak_ptr<CountedChild> w1 = p1;
|
||||
|
||||
//BOOST_CHECK_EQUAL(1, p1.use_count());
|
||||
|
||||
rbx::intrusive_weak_ptr<CountedChild> w2 = w1;
|
||||
|
||||
//BOOST_CHECK_EQUAL(1, p1.use_count());
|
||||
|
||||
rbx::intrusive_weak_ptr<Counted> w4(w1);
|
||||
rbx::intrusive_weak_ptr<Counted> w5(p1);
|
||||
rbx::intrusive_weak_ptr<Counted> w6(p1.get());
|
||||
|
||||
rbx::intrusive_weak_ptr<Counted> w;
|
||||
w = w1;
|
||||
w = p1;
|
||||
w = p1.get();
|
||||
|
||||
boost::intrusive_ptr<Counted> p2 = w1.lock();
|
||||
//BOOST_CHECK_EQUAL(2, p1.use_count());
|
||||
|
||||
BOOST_CHECK_EQUAL(1, Counted::count);
|
||||
|
||||
{
|
||||
if (boost::intrusive_ptr<Counted> p3 = w1.lock())
|
||||
//BOOST_CHECK_EQUAL(3, p1.use_count());
|
||||
;
|
||||
else
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
|
||||
p1.reset();
|
||||
|
||||
BOOST_CHECK_NO_THROW(boost::intrusive_ptr<Counted>(w1.lock()).get());
|
||||
|
||||
p2.reset();
|
||||
|
||||
BOOST_CHECK_EQUAL(0, Counted::count);
|
||||
//BOOST_CHECK_EQUAL(0, p1.use_count());
|
||||
|
||||
p2 = w1.lock();
|
||||
BOOST_CHECK(!p2);
|
||||
|
||||
//BOOST_CHECK_THROW(boost::intrusive_ptr<Counted>(w1.lock()).get(), rbx::bad_weak_ptr);
|
||||
}
|
||||
#ifndef RBX_PLATFORM_IOS
|
||||
|
||||
class OF
|
||||
: public rbx::intrusive_ptr_target<OF, int, 1, 2>
|
||||
{
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Overflow)
|
||||
{
|
||||
boost::intrusive_ptr<OF> of(new OF());
|
||||
boost::intrusive_ptr<OF> of2;
|
||||
BOOST_CHECK_THROW(of2 = of, rbx::too_many_refs);
|
||||
BOOST_CHECK_THROW(of2 = of, std::exception);
|
||||
|
||||
rbx::intrusive_weak_ptr<OF> w[10];
|
||||
w[0] = of;
|
||||
w[1] = w[0];
|
||||
BOOST_CHECK_THROW(w[2] = w[0], rbx::too_many_refs);
|
||||
BOOST_CHECK_THROW(w[2] = w[0], std::exception);
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "boost/shared_ptr.hpp"
|
||||
#include "boost/weak_ptr.hpp"
|
||||
#include "rbx/make_shared.h"
|
||||
|
||||
using namespace boost;
|
||||
|
||||
struct Counted : boost::noncopyable {
|
||||
static int count;
|
||||
Counted() { count++; }
|
||||
~Counted() { count--; }
|
||||
};
|
||||
int Counted::count = 0;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(MakeShared)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Destructor)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(0, Counted::count);
|
||||
shared_ptr<Counted> p = rbx::make_shared<Counted>();
|
||||
BOOST_CHECK_EQUAL(1, Counted::count);
|
||||
weak_ptr<Counted> w = p;
|
||||
BOOST_CHECK_EQUAL(1, Counted::count);
|
||||
p.reset();
|
||||
BOOST_CHECK_EQUAL(0, Counted::count);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
|
||||
@@ -0,0 +1,483 @@
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "rbx/signal.h"
|
||||
|
||||
class Foo {};
|
||||
|
||||
static void add(int i, int& result)
|
||||
{
|
||||
result += i;
|
||||
}
|
||||
|
||||
static void throw_runtime_error()
|
||||
{
|
||||
throw std::runtime_error("");
|
||||
}
|
||||
|
||||
static void exception_handler(std::exception& ex)
|
||||
{
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
|
||||
static void addConnection(int i, int& result, rbx::signal<void(int)>& sig1)
|
||||
{
|
||||
add(i, result);
|
||||
sig1.connect(boost::bind(&add, _1, boost::ref(result)));
|
||||
}
|
||||
static void removeConnection(int i, int& result, rbx::signals::connection& connection)
|
||||
{
|
||||
add(i, result);
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
static void append(std::string* s, const char* append)
|
||||
{
|
||||
*s += append;
|
||||
}
|
||||
|
||||
void emptyFunction()
|
||||
{
|
||||
}
|
||||
|
||||
void emptyFunction2(int)
|
||||
{
|
||||
}
|
||||
|
||||
class SignalsFixture
|
||||
{
|
||||
boost::function<void(std::exception&)> slot_exception_handler;
|
||||
public:
|
||||
SignalsFixture()
|
||||
{
|
||||
slot_exception_handler = rbx::signals::slot_exception_handler;
|
||||
rbx::signals::slot_exception_handler = &exception_handler;
|
||||
|
||||
}
|
||||
~SignalsFixture()
|
||||
{
|
||||
rbx::signals::slot_exception_handler = slot_exception_handler;
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(Signals, SignalsFixture)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SimpleTest)
|
||||
{
|
||||
rbx::signal<void(int)> sig1;
|
||||
|
||||
//char m[1111];
|
||||
//sprintf(m, "%d %d", rbx::signal<void(int)>::sizeof_slot(), rbx::signal<void(int, std::string, bool)>::sizeof_slot());
|
||||
|
||||
int result = 0;
|
||||
rbx::signals::connection connection = sig1.connect(boost::bind(&add, _1, boost::ref(result)));
|
||||
sig1(12);
|
||||
BOOST_CHECK_EQUAL(12, result);
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
result = 0;
|
||||
sig1(12);
|
||||
BOOST_CHECK_EQUAL(0, result);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(EmptyTest)
|
||||
{
|
||||
rbx::signal<void(int)> sig1;
|
||||
BOOST_CHECK(sig1.empty());
|
||||
|
||||
int result = 0;
|
||||
rbx::signals::connection connection = sig1.connect(boost::bind(&add, _1, boost::ref(result)));
|
||||
BOOST_CHECK(!sig1.empty());
|
||||
|
||||
rbx::signals::connection connection2 = sig1.connect(boost::bind(&add, _1, boost::ref(result)));
|
||||
BOOST_CHECK(!sig1.empty());
|
||||
|
||||
connection.disconnect();
|
||||
BOOST_CHECK(!sig1.empty());
|
||||
|
||||
connection2.disconnect();
|
||||
BOOST_CHECK(sig1.empty());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SimpleTest2)
|
||||
{
|
||||
rbx::signal<void(bool, int)> sig1;
|
||||
int result = 0;
|
||||
rbx::signals::connection connection = sig1.connect(boost::bind(&add, _2, boost::ref(result)));
|
||||
sig1(true, 12);
|
||||
BOOST_CHECK_EQUAL(12, result);
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
result = 0;
|
||||
sig1(false, 12);
|
||||
BOOST_CHECK_EQUAL(0, result);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SimpleTest3)
|
||||
{
|
||||
rbx::signal<void(bool, const char*, int)> sig1;
|
||||
int result = 0;
|
||||
rbx::signals::connection connection = sig1.connect(boost::bind(&add, _3, boost::ref(result)));
|
||||
sig1(false, "", 12);
|
||||
BOOST_CHECK_EQUAL(12, result);
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
result = 0;
|
||||
sig1(false, "", 12);
|
||||
BOOST_CHECK_EQUAL(0, result);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SimpleTest4)
|
||||
{
|
||||
rbx::signal<void(bool, const char*, Foo, int)> sig1;
|
||||
int result = 0;
|
||||
rbx::signals::connection connection = sig1.connect(boost::bind(&add, _4, boost::ref(result)));
|
||||
sig1(false, "", Foo(), 12);
|
||||
BOOST_CHECK_EQUAL(12, result);
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
result = 0;
|
||||
sig1(false, "", Foo(), 12);
|
||||
BOOST_CHECK_EQUAL(0, result);
|
||||
}
|
||||
|
||||
|
||||
/* A simplified version of PartInstance::TouchedSignal */
|
||||
class TouchedSignal : public rbx::signal<void()>
|
||||
{
|
||||
private:
|
||||
typedef rbx::signal<void()> Super;
|
||||
|
||||
class TouchedSlot
|
||||
{
|
||||
boost::function<void()> inner;
|
||||
public:
|
||||
TouchedSlot(const boost::function<void()>& inner):inner(inner)
|
||||
{
|
||||
}
|
||||
TouchedSlot(const TouchedSlot& other) : inner(other.inner)
|
||||
{
|
||||
}
|
||||
|
||||
TouchedSlot& operator=(const TouchedSlot& other);
|
||||
~TouchedSlot()
|
||||
{
|
||||
// Try to create a deadlock
|
||||
rbx::signal<void()> sig;
|
||||
rbx::signals::scoped_connection connection(sig.connect(boost::bind(emptyFunction)));
|
||||
sig();
|
||||
}
|
||||
void operator()()
|
||||
{
|
||||
if (inner)
|
||||
inner();
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
template<typename F>
|
||||
rbx::signals::connection connect(F slot)
|
||||
{
|
||||
return Super::connect(TouchedSlot(slot));
|
||||
}
|
||||
static void disc(rbx::signals::connection* c)
|
||||
{
|
||||
c->disconnect();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Deadlock)
|
||||
{
|
||||
// This code will deadlock if ~TouchedSignal is called within a signal mutex.
|
||||
// It happened when I tried to optimize next() by passig the shared_ptr<slot> by
|
||||
// reference. This caused the slot to be collected within the mutex, which has side
|
||||
// effects. We must avoid any side effects within the mutex to avoid deadlocks and
|
||||
// also to avoid thread starvation if the mutex is a spin mutex.
|
||||
TouchedSignal* tester = new TouchedSignal();
|
||||
rbx::signals::connection connection;
|
||||
connection = tester->connect(boost::bind(TouchedSignal::disc, &connection));
|
||||
(*tester)();
|
||||
connection.disconnect();
|
||||
delete tester;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ExceptionHandling)
|
||||
{
|
||||
int exceptionCount = 0;
|
||||
rbx::signals::slot_exception_handler = boost::bind(add, 1, boost::ref(exceptionCount));
|
||||
|
||||
rbx::signal<void(int)> sig1;
|
||||
rbx::signals::connection connection = sig1.connect(boost::bind(throw_runtime_error));
|
||||
|
||||
int result = 0;
|
||||
sig1.connect(boost::bind(&add, _1, boost::ref(result)));
|
||||
sig1(12);
|
||||
BOOST_CHECK_EQUAL(12, result);
|
||||
BOOST_CHECK_EQUAL(1, exceptionCount);
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
result = 0;
|
||||
sig1(12);
|
||||
BOOST_CHECK_EQUAL(12, result);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(EmptySlot)
|
||||
{
|
||||
rbx::signal<void(int)> sig1;
|
||||
int result = 0;
|
||||
rbx::signals::connection connection = sig1.connect(boost::bind(emptyFunction2, _1));
|
||||
sig1(12);
|
||||
BOOST_CHECK_EQUAL(0, result);
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
result = 0;
|
||||
sig1(12);
|
||||
BOOST_CHECK_EQUAL(0, result);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(RemoveWhileFiring)
|
||||
{
|
||||
rbx::signal<void(int)> sig1;
|
||||
int result = 0;
|
||||
|
||||
rbx::signals::connection connectionToRemove;
|
||||
|
||||
// add a dummy slot
|
||||
sig1.connect(boost::bind(&add, _1, boost::ref(result)));
|
||||
|
||||
rbx::signals::connection connectionThatRemoves = sig1.connect(boost::bind(&removeConnection, _1, boost::ref(result), boost::ref(connectionToRemove)));
|
||||
|
||||
// add another slot
|
||||
connectionToRemove = sig1.connect(boost::bind(&add, _1, boost::ref(result)));
|
||||
|
||||
BOOST_CHECK(connectionToRemove.connected());
|
||||
result = 0;
|
||||
sig1(1);
|
||||
BOOST_CHECK(!connectionToRemove.connected());
|
||||
BOOST_CHECK_EQUAL(3, result);
|
||||
|
||||
// Now call them again, expecting to lose one slot call
|
||||
result = 0;
|
||||
sig1(1);
|
||||
BOOST_CHECK_EQUAL(2, result);
|
||||
|
||||
// Now cause the slot to remove its own connection:
|
||||
connectionToRemove = connectionThatRemoves;
|
||||
|
||||
BOOST_CHECK(connectionToRemove.connected());
|
||||
result = 0;
|
||||
sig1(1);
|
||||
BOOST_CHECK(!connectionToRemove.connected());
|
||||
BOOST_CHECK_EQUAL(2, result);
|
||||
|
||||
result = 0;
|
||||
sig1(1);
|
||||
BOOST_CHECK_EQUAL(1, result);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AddWhileFiring)
|
||||
{
|
||||
rbx::signal<void(int)> sig1;
|
||||
int result = 0;
|
||||
|
||||
// add a dummy slot
|
||||
sig1.connect(boost::bind(&add, _1, boost::ref(result)));
|
||||
|
||||
rbx::signals::connection connection = sig1.connect(boost::bind(&addConnection, _1, boost::ref(result), boost::ref(sig1)));
|
||||
|
||||
result = 0;
|
||||
sig1(1);
|
||||
BOOST_CHECK_EQUAL(2, result);
|
||||
result = 0;
|
||||
sig1(1);
|
||||
BOOST_CHECK_EQUAL(3, result);
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
result = 0;
|
||||
sig1(1);
|
||||
BOOST_CHECK_EQUAL(3, result);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(FireOrder)
|
||||
{
|
||||
// This may not be guaranteed in the future, but slots are added to the head of the chain.
|
||||
// The reason for having this test is to warn that there may be breaking changes.
|
||||
rbx::signal<void(std::string*)> sig1;
|
||||
std::string result;
|
||||
sig1.connect(boost::bind(&append, _1, "World"));
|
||||
sig1.connect(boost::bind(&append, _1, "Hello"));
|
||||
sig1(&result);
|
||||
BOOST_CHECK_EQUAL(result, "HelloWorld");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DoubleDisconnect)
|
||||
{
|
||||
rbx::signal<void(std::string*)> sig1;
|
||||
std::string result;
|
||||
rbx::signals::connection c1 = sig1.connect(boost::bind(&append, _1, "Hi"));
|
||||
rbx::signals::connection c2 = c1;
|
||||
|
||||
sig1(&result);
|
||||
BOOST_CHECK_EQUAL(result, "Hi");
|
||||
|
||||
c1.disconnect();
|
||||
|
||||
sig1(&result);
|
||||
BOOST_CHECK_EQUAL(result, "Hi");
|
||||
|
||||
c2.disconnect();
|
||||
|
||||
sig1(&result);
|
||||
BOOST_CHECK_EQUAL(result, "Hi");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DisconnectWhileFiring)
|
||||
{
|
||||
rbx::signal<void(rbx::signals::connection*)> sig1;
|
||||
rbx::signals::connection connection = sig1.connect(boost::bind(&rbx::signals::connection::disconnect, _1));
|
||||
BOOST_CHECK(connection.connected());
|
||||
sig1(&connection);
|
||||
BOOST_CHECK(!connection.connected());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AssignmentOperator)
|
||||
{
|
||||
rbx::signal<void(std::string*)> sig1;
|
||||
std::string result;
|
||||
|
||||
{
|
||||
rbx::signals::scoped_connection connection(sig1.connect(boost::bind(&append, _1, "[Not Me!]")));
|
||||
connection = sig1.connect(boost::bind(&append, _1, "Hello"));
|
||||
sig1(&result);
|
||||
BOOST_CHECK_EQUAL(result, "Hello");
|
||||
}
|
||||
|
||||
result.clear();
|
||||
sig1(&result);
|
||||
BOOST_CHECK_EQUAL(result, "");
|
||||
}
|
||||
|
||||
static void doubleDisconnect(rbx::signals::connection& connection, std::string* s)
|
||||
{
|
||||
*s += "Hi";
|
||||
connection.disconnect();
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
static void dont_call_me()
|
||||
{
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
|
||||
static void remove_connections(rbx::signals::connection* c1, rbx::signals::connection* c2, rbx::signals::connection* c3)
|
||||
{
|
||||
c3->disconnect();
|
||||
c2->disconnect();
|
||||
c1->disconnect();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(MultiDisconnect)
|
||||
{
|
||||
// Tests CS1502 - a bug that Simon found
|
||||
rbx::signal<void()> sig1;
|
||||
rbx::signals::connection c1 = sig1.connect(boost::bind(&dont_call_me));
|
||||
rbx::signals::connection c2 = sig1.connect(boost::bind(&dont_call_me));
|
||||
rbx::signals::connection c3;
|
||||
c3 = sig1.connect(boost::bind(remove_connections, &c1, &c2, &c3));
|
||||
sig1();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ReentrantDoubleDisconnect)
|
||||
{
|
||||
rbx::signal<void(std::string*)> sig1;
|
||||
std::string result;
|
||||
|
||||
rbx::signals::connection connection = sig1.connect(boost::bind(doubleDisconnect, boost::ref(connection), &result));
|
||||
sig1(&result);
|
||||
BOOST_CHECK_EQUAL(result, "Hi");
|
||||
}
|
||||
|
||||
static void reset(rbx::signal<void(std::string*)>& sig1, rbx::signals::scoped_connection& connection, std::string message, std::string* s)
|
||||
{
|
||||
*s += message;
|
||||
connection = sig1.connect(boost::bind(&reset, boost::ref(sig1), boost::ref(connection), message + "#", _1));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ReentrantResetScopedConnection)
|
||||
{
|
||||
rbx::signal<void(std::string*)> sig1;
|
||||
std::string result;
|
||||
|
||||
rbx::signals::scoped_connection connection;
|
||||
reset(sig1, connection, "Reset", &result);
|
||||
BOOST_CHECK_EQUAL(result, "Reset");
|
||||
|
||||
result.clear();
|
||||
sig1.connect(boost::bind(&append, _1, "Hello"));
|
||||
sig1(&result);
|
||||
BOOST_CHECK_EQUAL(result, "HelloReset#");
|
||||
|
||||
result.clear();
|
||||
sig1(&result);
|
||||
BOOST_CHECK_EQUAL(result, "Reset##Hello");
|
||||
|
||||
result.clear();
|
||||
sig1(&result);
|
||||
BOOST_CHECK_EQUAL(result, "Reset###Hello");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SlotChain)
|
||||
{
|
||||
// Make sure a huge chain of slots doesn't cause a stack crash on destruction
|
||||
// See DE131
|
||||
rbx::signal<void()> signal;
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
signal.connect(boost::function<void()>());
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ReverseDestruction)
|
||||
{
|
||||
// Make sure it is safe to disconnect a connection after the slot has been destroyed
|
||||
rbx::signals::connection connection;
|
||||
{
|
||||
rbx::signal<void()> signal;
|
||||
connection = signal.connect(boost::function<void()>());
|
||||
}
|
||||
connection.disconnect();
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
|
||||
#ifndef _DEBUG
|
||||
BOOST_AUTO_TEST_CASE(PerfSignal)
|
||||
{
|
||||
rbx::signal<void(std::string, int)> sig1;
|
||||
int result = 0;
|
||||
rbx::signals::scoped_connection connection[10];
|
||||
for (int i = 0; i < 5; ++i)
|
||||
connection[i] = sig1.connect(boost::bind(&add, _2, boost::ref(result)));
|
||||
|
||||
for (int i = 0; i < 1e6; ++i)
|
||||
sig1("Hello World", 12);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PerfConnect)
|
||||
{
|
||||
rbx::signal<void(bool, int)> sig1;
|
||||
int result = 0;
|
||||
for (int i = 0; i < 1e6; ++i)
|
||||
{
|
||||
rbx::signals::connection connection = sig1.connect(boost::bind(&add, _2, boost::ref(result)));
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -0,0 +1,52 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "concurrent.h"
|
||||
|
||||
#include "rbx/threadsafe.h"
|
||||
|
||||
namespace spin_mutex_test
|
||||
{
|
||||
BOOST_AUTO_TEST_SUITE(spin_mutex)
|
||||
|
||||
struct ConcurrentAccess
|
||||
{
|
||||
ConcurrentAccess()
|
||||
{
|
||||
const int threads = 8;
|
||||
const int iterations = 1000000;
|
||||
rbx::spin_mutex mutex;
|
||||
int value = 0;
|
||||
int expected_value = 0;
|
||||
|
||||
for (int i = 1; i <= threads; ++i)
|
||||
expected_value += i * iterations;
|
||||
|
||||
BOOST_CHECK_EQUAL(util::ConcurrentLoops<Adder>::run(Adder(mutex, value), iterations, threads), 0);
|
||||
BOOST_CHECK_EQUAL(value, expected_value);
|
||||
}
|
||||
|
||||
private:
|
||||
struct Adder
|
||||
{
|
||||
int operator()(int index)
|
||||
{
|
||||
rbx::spin_mutex::scoped_lock lock(mutex_);
|
||||
value_ += index + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Adder(rbx::spin_mutex& mutex, int& value) : mutex_(mutex), value_(value) {}
|
||||
|
||||
private:
|
||||
rbx::spin_mutex& mutex_;
|
||||
int& value_;
|
||||
};
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE(concurrent_access)
|
||||
{
|
||||
ConcurrentAccess test;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END() // spin_mutex
|
||||
|
||||
} // namespace spin_mutex_test
|
||||
@@ -0,0 +1,129 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include "rbx/trie.h"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Trie)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(NameConflict)
|
||||
{
|
||||
int v;
|
||||
|
||||
rbx::trie<int, 10> trie;
|
||||
trie["ab"] = 1;
|
||||
|
||||
BOOST_CHECK(trie.lookup("ab", v));
|
||||
BOOST_CHECK_EQUAL(v, 1);
|
||||
|
||||
trie["a"] = 2;
|
||||
|
||||
BOOST_CHECK(trie.lookup("ab", v));
|
||||
BOOST_CHECK_EQUAL(v, 1);
|
||||
BOOST_CHECK(trie.lookup("a", v));
|
||||
BOOST_CHECK_EQUAL(v, 2);
|
||||
|
||||
trie["ac"] = 3;
|
||||
|
||||
BOOST_CHECK(trie.lookup("ab", v));
|
||||
BOOST_CHECK_EQUAL(v, 1);
|
||||
BOOST_CHECK(trie.lookup("a", v));
|
||||
BOOST_CHECK_EQUAL(v, 2);
|
||||
BOOST_CHECK(trie.lookup("ac", v));
|
||||
BOOST_CHECK_EQUAL(v, 3);
|
||||
|
||||
trie["acart"] = 4;
|
||||
|
||||
BOOST_CHECK(!trie.lookup("aca", v));
|
||||
BOOST_CHECK(!trie.lookup("acar", v));
|
||||
BOOST_CHECK(trie.lookup("acart", v));
|
||||
BOOST_CHECK_EQUAL(v, 4);
|
||||
|
||||
BOOST_CHECK(trie.lookup("ab", v));
|
||||
BOOST_CHECK_EQUAL(v, 1);
|
||||
BOOST_CHECK(trie.lookup("a", v));
|
||||
BOOST_CHECK_EQUAL(v, 2);
|
||||
BOOST_CHECK(trie.lookup("ac", v));
|
||||
BOOST_CHECK_EQUAL(v, 3);
|
||||
}
|
||||
|
||||
|
||||
static std::string newKey()
|
||||
{
|
||||
std::string key;
|
||||
for (int k = 0; k < 10; ++k)
|
||||
{
|
||||
int r = 32 + rand() % 96;
|
||||
key += (char) r;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
typedef rbx::trie<int, 30> Trie;
|
||||
|
||||
static std::string init(Trie& trie, std::map<std::string, int>& map, boost::unordered_map<std::string, int>& hashmap)
|
||||
{
|
||||
std::string key;
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
key = newKey();
|
||||
static int j = 0;
|
||||
int value = ++j;
|
||||
|
||||
trie[key.c_str()] = value;
|
||||
map[key] = value;
|
||||
hashmap[key] = value;
|
||||
int v;
|
||||
BOOST_REQUIRE(trie.lookup(key.c_str(), v));
|
||||
BOOST_REQUIRE_EQUAL(v, value);
|
||||
BOOST_REQUIRE_EQUAL(map[key], value);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SimpleTest)
|
||||
{
|
||||
Trie trie;
|
||||
std::map<std::string, int> map;
|
||||
boost::unordered_map<std::string, int> hashmap;
|
||||
std::string key = init(trie, map, hashmap);
|
||||
}
|
||||
|
||||
#ifndef _DEBUG
|
||||
BOOST_AUTO_TEST_CASE(PerfTrie)
|
||||
{
|
||||
Trie trie;
|
||||
std::map<std::string, int> map;
|
||||
boost::unordered_map<std::string, int> hashmap;
|
||||
std::string key = init(trie, map, hashmap);
|
||||
|
||||
int v;
|
||||
for (int i = 0; i < 1000000; ++i)
|
||||
trie.lookup(key.c_str(), v);
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE(PerfMap)
|
||||
{
|
||||
Trie trie;
|
||||
std::map<std::string, int> map;
|
||||
boost::unordered_map<std::string, int> hashmap;
|
||||
std::string key = init(trie, map, hashmap);
|
||||
|
||||
for (int i = 0; i < 1000000; ++i)
|
||||
map.find(key);
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE(PerfHashMap)
|
||||
{
|
||||
Trie trie;
|
||||
std::map<std::string, int> map;
|
||||
boost::unordered_map<std::string, int> hashmap;
|
||||
std::string key = init(trie, map, hashmap);
|
||||
|
||||
for (int i = 0; i < 1000000; ++i)
|
||||
hashmap.find(key);
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
Reference in New Issue
Block a user