http://git-wip-us.apache.org/repos/asf/ignite/blob/58a665aa/modules/platform/src/main/cpp/core-test/project/vs/core-test.vcxproj ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/cpp/core-test/project/vs/core-test.vcxproj b/modules/platform/src/main/cpp/core-test/project/vs/core-test.vcxproj new file mode 100644 index 0000000..aa8cb98 --- /dev/null +++ b/modules/platform/src/main/cpp/core-test/project/vs/core-test.vcxproj @@ -0,0 +1,174 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\..\common\project\vs\common.vcxproj"> + <Project>{4f7e4917-4612-4b96-9838-025711ade391}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\core\project\vs\core.vcxproj"> + <Project>{e2dea693-f2ea-43c2-a813-053378f6e4db}</Project> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <None Include="..\..\config\cache-query.xml" /> + <None Include="..\..\config\cache-test.xml" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\cache_test.cpp" /> + <ClCompile Include="..\..\src\concurrent_test.cpp" /> + <ClCompile Include="..\..\src\ignition_test.cpp" /> + <ClCompile Include="..\..\src\handle_registry_test.cpp" /> + <ClCompile Include="..\..\src\portable_reader_writer_raw_test.cpp" /> + <ClCompile Include="..\..\src\portable_reader_writer_test.cpp" /> + <ClCompile Include="..\..\src\portable_session_test.cpp" /> + <ClCompile Include="..\..\src\portable_test_defs.cpp" /> + <ClCompile Include="..\..\src\cache_query_test.cpp" /> + <ClCompile Include="..\..\src\teamcity_boost.cpp" /> + <ClCompile Include="..\..\src\teamcity_messages.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\include\ignite\portable_test_defs.h" /> + <ClInclude Include="..\..\include\ignite\portable_test_utils.h" /> + <ClInclude Include="..\..\include\teamcity_messages.h" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{133A22DB-FD60-44B9-B5E3-6CBB3EA5ABF0}</ProjectGuid> + <RootNamespace>coretest</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v100</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v100</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v100</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v100</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" 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|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)'=='Release|x64'" 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)'=='Release|Win32'" 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 Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\core\include;$(ProjectDir)\..\..\..\core\os\win\include;$(ProjectDir)\..\..\include;$(BOOST_HOME)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;IGNITE_IMPL;BOOST_DATE_TIME_NO_LIB;BOOST_REGEX_NO_LIB;_CRT_SECURE_NO_WARNINGS;IGNITE_FRIEND;_CRTDBG_MAP_ALLOC;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ExceptionHandling>Async</ExceptionHandling> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>$(BOOST_HOME)\lib64-msvc-10.0\libboost_unit_test_framework-vc100-mt-gd-1_58.lib;%(AdditionalDependencies)</AdditionalDependencies> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\core\include;$(ProjectDir)\..\..\..\core\os\win\include;$(ProjectDir)\..\..\include;$(BOOST_HOME)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;IGNITE_IMPL;BOOST_DATE_TIME_NO_LIB;BOOST_REGEX_NO_LIB;_CRT_SECURE_NO_WARNINGS;IGNITE_FRIEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ExceptionHandling>Async</ExceptionHandling> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>$(BOOST_HOME)\lib64-msvc-10.0\libboost_unit_test_framework-vc100-mt-gd-1_58.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\core\include;$(ProjectDir)\..\..\..\core\os\win\include;$(ProjectDir)\..\..\include;$(BOOST_HOME)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;IGNITE_IMPL;BOOST_DATE_TIME_NO_LIB;BOOST_REGEX_NO_LIB;_CRT_SECURE_NO_WARNINGS;IGNITE_FRIEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ExceptionHandling>Async</ExceptionHandling> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>$(BOOST_HOME)\lib64-msvc-10.0\libboost_unit_test_framework-vc100-mt-1_58.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\core\include;$(ProjectDir)\..\..\..\core\os\win\include;$(ProjectDir)\..\..\include;$(BOOST_HOME)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;IGNITE_IMPL;BOOST_DATE_TIME_NO_LIB;BOOST_REGEX_NO_LIB;_CRT_SECURE_NO_WARNINGS;IGNITE_FRIEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ExceptionHandling>Async</ExceptionHandling> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>$(BOOST_HOME)\lib64-msvc-10.0\libboost_unit_test_framework-vc100-mt-1_58.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/58a665aa/modules/platform/src/main/cpp/core-test/project/vs/core-test.vcxproj.filters ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/cpp/core-test/project/vs/core-test.vcxproj.filters b/modules/platform/src/main/cpp/core-test/project/vs/core-test.vcxproj.filters new file mode 100644 index 0000000..7e8dd95 --- /dev/null +++ b/modules/platform/src/main/cpp/core-test/project/vs/core-test.vcxproj.filters @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="..\..\src\cache_test.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\concurrent_test.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\ignition_test.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\handle_registry_test.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\portable_reader_writer_raw_test.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\portable_reader_writer_test.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\portable_session_test.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\portable_test_defs.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cache_query_test.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\teamcity_boost.cpp"> + <Filter>TeamCity</Filter> + </ClCompile> + <ClCompile Include="..\..\src\teamcity_messages.cpp"> + <Filter>TeamCity</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\include\ignite\portable_test_defs.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\portable_test_utils.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\teamcity_messages.h"> + <Filter>TeamCity</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <Filter Include="Code"> + <UniqueIdentifier>{486c367c-57e9-430a-80f0-39fd5b09bc64}</UniqueIdentifier> + </Filter> + <Filter Include="Configs"> + <UniqueIdentifier>{a46d9d4c-44eb-40da-b4f6-89cc43b70c12}</UniqueIdentifier> + </Filter> + <Filter Include="TeamCity"> + <UniqueIdentifier>{76bceab0-e251-445f-88c3-3f6f8739423b}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <None Include="..\..\config\cache-test.xml"> + <Filter>Configs</Filter> + </None> + <None Include="..\..\config\cache-query.xml"> + <Filter>Configs</Filter> + </None> + </ItemGroup> +</Project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/58a665aa/modules/platform/src/main/cpp/core-test/src/cache_query_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/cpp/core-test/src/cache_query_test.cpp b/modules/platform/src/main/cpp/core-test/src/cache_query_test.cpp new file mode 100644 index 0000000..6ccfd51 --- /dev/null +++ b/modules/platform/src/main/cpp/core-test/src/cache_query_test.cpp @@ -0,0 +1,651 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MSC_VER + #define BOOST_TEST_DYN_LINK +#endif + +#include <sstream> + +#include <boost/test/unit_test.hpp> + +#include "ignite/impl/utils.h" +#include "ignite/cache/cache.h" +#include "ignite/cache/query/query_cursor.h" +#include "ignite/cache/query/query_sql.h" +#include "ignite/cache/query/query_text.h" +#include "ignite/ignite.h" +#include "ignite/ignition.h" + +using namespace boost::unit_test; + +using namespace ignite; +using namespace ignite::cache; +using namespace ignite::cache::query; +using namespace ignite::impl::utils; + +/** + * Person class for query tests. + */ +class IGNITE_IMPORT_EXPORT QueryPerson +{ +public: + /** + * Constructor. + */ + QueryPerson() : name(NULL), age(0) + { + // No-op. + } + + /** + * Constructor. + * + * @param name Name. + * @param age Age. + */ + QueryPerson(std::string name, int age) : name(CopyChars(name.c_str())), age(age) + { + // No-op. + } + + /** + * Copy constructor. + * + * @param other Other instance. + */ + QueryPerson(const QueryPerson& other) + { + name = CopyChars(other.name); + age = other.age; + } + + /** + * Assignment operator. + * + * @param other Other instance. + * @return This instance. + */ + QueryPerson& operator=(const QueryPerson& other) + { + if (&other != this) + { + QueryPerson tmp(other); + + char* name0 = name; + int age0 = age; + + name = tmp.name; + age = tmp.age; + + tmp.name = name0; + tmp.age = age0; + } + + return *this; + } + + /** + * Destructor. + */ + ~QueryPerson() + { + ReleaseChars(name); + } + + /** + * Get name. + * + * @return Name. + */ + std::string GetName() + { + return name ? std::string(name) : std::string(); + } + + /** + * Get age. + * + * @return Age. + */ + int32_t GetAge() + { + return age; + } + +private: + /** Name. */ + char* name; + + /** Age. */ + int age; +}; + +namespace ignite +{ + namespace portable + { + /** + * Portable type definition. + */ + IGNITE_PORTABLE_TYPE_START(QueryPerson) + IGNITE_PORTABLE_GET_TYPE_ID_AS_HASH(QueryPerson) + IGNITE_PORTABLE_GET_TYPE_NAME_AS_IS(QueryPerson) + IGNITE_PORTABLE_GET_FIELD_ID_AS_HASH + IGNITE_PORTABLE_GET_HASH_CODE_ZERO(QueryPerson) + IGNITE_PORTABLE_IS_NULL_FALSE(QueryPerson) + IGNITE_PORTABLE_GET_NULL_DEFAULT_CTOR(QueryPerson) + + void Write(PortableWriter& writer, QueryPerson obj) + { + writer.WriteString("name", obj.GetName()); + writer.WriteInt32("age", obj.GetAge()); + } + + QueryPerson Read(PortableReader& reader) + { + std::string name = reader.ReadString("name"); + int age = reader.ReadInt32("age"); + + return QueryPerson(name, age); + } + + IGNITE_PORTABLE_TYPE_END + } +} + +/** Node started during the test. */ +Ignite grid = Ignite(); + +/** Cache accessor. */ +Cache<int, QueryPerson> GetCache() +{ + return grid.GetCache<int, QueryPerson>("cache"); +} + +/** + * Test setup fixture. + */ +struct CacheQueryTestSuiteFixture { + /** + * Constructor. + */ + CacheQueryTestSuiteFixture() + { + IgniteConfiguration cfg; + + IgniteJvmOption opts[5]; + + opts[0] = IgniteJvmOption("-Xdebug"); + opts[1] = IgniteJvmOption("-Xnoagent"); + opts[2] = IgniteJvmOption("-Djava.compiler=NONE"); + opts[3] = IgniteJvmOption("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"); + opts[4] = IgniteJvmOption("-XX:+HeapDumpOnOutOfMemoryError"); + + cfg.jvmOptsLen = 5; + cfg.jvmOpts = opts; + + cfg.jvmInitMem = 1024; + cfg.jvmMaxMem = 4096; + + char* cfgPath = getenv("IGNITE_NATIVE_TEST_CPP_CONFIG_PATH"); + + std::string cfgPathStr = std::string(cfgPath).append("/").append("cache-query.xml"); + + cfg.springCfgPath = const_cast<char*>(cfgPathStr.c_str()); + + IgniteError err; + + Ignite grid0 = Ignition::Start(cfg, &err); + + if (err.GetCode() != IgniteError::IGNITE_SUCCESS) + BOOST_ERROR(err.GetText()); + + grid = grid0; + } + + /** + * Destructor. + */ + ~CacheQueryTestSuiteFixture() + { + Ignition::Stop(grid.GetName(), true); + } +}; + +/** + * Ensure that HasNext() fails. + * + * @param cur Cursor. + */ +void CheckHasNextFail(QueryCursor<int, QueryPerson>& cur) +{ + try + { + cur.HasNext(); + + BOOST_FAIL("Must fail."); + } + catch (IgniteError& err) + { + BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_GENERIC); + } +} + +/** + * Ensure that GetNext() fails. + * + * @param cur Cursor. + */ +void CheckGetNextFail(QueryCursor<int, QueryPerson>& cur) +{ + try + { + cur.GetNext(); + + BOOST_FAIL("Must fail."); + } + catch (IgniteError& err) + { + BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_GENERIC); + } +} + +/** + * Ensure that GetAll() fails. + * + * @param cur Cursor. + */ +void CheckGetAllFail(QueryCursor<int, QueryPerson>& cur) +{ + try + { + std::vector<CacheEntry<int, QueryPerson>> res; + + cur.GetAll(res); + + BOOST_FAIL("Must fail."); + } + catch (IgniteError& err) + { + BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_GENERIC); + } +} + +/** + * Check empty result through iteration. + * + * @param cur Cursor. + */ +void CheckEmpty(QueryCursor<int, QueryPerson>& cur) +{ + BOOST_REQUIRE(!cur.HasNext()); + + CheckGetNextFail(cur); + CheckGetAllFail(cur); +} + +/** + * Check empty result through GetAll(). + * + * @param cur Cursor. + */ +void CheckEmptyGetAll(QueryCursor<int, QueryPerson>& cur) +{ + std::vector<CacheEntry<int, QueryPerson>> res; + + cur.GetAll(res); + + BOOST_REQUIRE(res.size() == 0); + + CheckHasNextFail(cur); + CheckGetNextFail(cur); +} + +/** + * Check single result through iteration. + * + * @param cur Cursor. + * @param key1 Key. + * @param name1 Name. + * @param age1 Age. + */ +void CheckSingle(QueryCursor<int, QueryPerson>& cur, int key, std::string name, int age) +{ + BOOST_REQUIRE(cur.HasNext()); + + CheckGetAllFail(cur); + + CacheEntry<int, QueryPerson> entry = cur.GetNext(); + + CheckGetAllFail(cur); + + BOOST_REQUIRE(entry.GetKey() == key); + BOOST_REQUIRE(entry.GetValue().GetName().compare(name) == 0); + BOOST_REQUIRE(entry.GetValue().GetAge() == age); + + BOOST_REQUIRE(!cur.HasNext()); + + CheckGetNextFail(cur); + CheckGetAllFail(cur); +} + +/** + * Check single result through GetAll(). + * + * @param cur Cursor. + * @param key1 Key. + * @param name1 Name. + * @param age1 Age. + */ +void CheckSingleGetAll(QueryCursor<int, QueryPerson>& cur, int key, std::string name, int age) +{ + std::vector<CacheEntry<int, QueryPerson>> res; + + cur.GetAll(res); + + CheckHasNextFail(cur); + CheckGetNextFail(cur); + CheckGetAllFail(cur); + + BOOST_REQUIRE(res.size() == 1); + + BOOST_REQUIRE(res[0].GetKey() == 1); + BOOST_REQUIRE(res[0].GetValue().GetName().compare(name) == 0); + BOOST_REQUIRE(res[0].GetValue().GetAge() == age); + + CheckHasNextFail(cur); + CheckGetNextFail(cur); + CheckGetAllFail(cur); +} + +/** + * Check multiple results through iteration. + * + * @param cur Cursor. + * @param key1 Key 1. + * @param name1 Name 1. + * @param age1 Age 1. + * @param key2 Key 2. + * @param name2 Name 2. + * @param age2 Age 2. + */ +void CheckMultiple(QueryCursor<int, QueryPerson>& cur, int key1, std::string name1, + int age1, int key2, std::string name2, int age2) +{ + for (int i = 0; i < 2; i++) + { + BOOST_REQUIRE(cur.HasNext()); + + CheckGetAllFail(cur); + + CacheEntry<int, QueryPerson> entry = cur.GetNext(); + + CheckGetAllFail(cur); + + if (entry.GetKey() == key1) + { + BOOST_REQUIRE(entry.GetValue().GetName().compare(name1) == 0); + BOOST_REQUIRE(entry.GetValue().GetAge() == age1); + } + else if (entry.GetKey() == key2) + { + BOOST_REQUIRE(entry.GetValue().GetName().compare(name2) == 0); + BOOST_REQUIRE(entry.GetValue().GetAge() == age2); + } + else + BOOST_FAIL("Unexpected entry."); + } + + BOOST_REQUIRE(!cur.HasNext()); + + CheckGetNextFail(cur); + CheckGetAllFail(cur); +} + +/** + * Check multiple results through GetAll(). + * + * @param cur Cursor. + * @param key1 Key 1. + * @param name1 Name 1. + * @param age1 Age 1. + * @param key2 Key 2. + * @param name2 Name 2. + * @param age2 Age 2. + */ +void CheckMultipleGetAll(QueryCursor<int, QueryPerson>& cur, int key1, std::string name1, int age1, + int key2, std::string name2, int age2) +{ + std::vector<CacheEntry<int, QueryPerson>> res; + + cur.GetAll(res); + + CheckHasNextFail(cur); + CheckGetNextFail(cur); + CheckGetAllFail(cur); + + BOOST_REQUIRE(res.size() == 2); + + for (int i = 0; i < 2; i++) + { + CacheEntry<int, QueryPerson> entry = res[i]; + + if (entry.GetKey() == key1) + { + BOOST_REQUIRE(entry.GetValue().GetName().compare(name1) == 0); + BOOST_REQUIRE(entry.GetValue().GetAge() == age1); + } + else if (entry.GetKey() == key2) + { + BOOST_REQUIRE(entry.GetValue().GetName().compare(name2) == 0); + BOOST_REQUIRE(entry.GetValue().GetAge() == age2); + } + else + BOOST_FAIL("Unexpected entry."); + } +} + +BOOST_FIXTURE_TEST_SUITE(CacheQueryTestSuite, CacheQueryTestSuiteFixture) + +/** + * Test SQL query. + */ +BOOST_AUTO_TEST_CASE(TestSqlQuery) +{ + Cache<int, QueryPerson> cache = GetCache(); + + // Test query with no results. + SqlQuery qry("QueryPerson", "age < 20"); + + QueryCursor<int, QueryPerson> cursor = cache.Query(qry); + CheckEmpty(cursor); + + cursor = cache.Query(qry); + CheckEmptyGetAll(cursor); + + // Test simple query. + cache.Put(1, QueryPerson("A1", 10)); + cache.Put(2, QueryPerson("A2", 20)); + + cursor = cache.Query(qry); + CheckSingle(cursor, 1, "A1", 10); + + cursor = cache.Query(qry); + CheckSingleGetAll(cursor, 1, "A1", 10); + + // Test simple local query. + qry.SetLocal(true); + + cursor = cache.Query(qry); + CheckSingle(cursor, 1, "A1", 10); + + cursor = cache.Query(qry); + CheckSingleGetAll(cursor, 1, "A1", 10); + + // Test query with arguments. + qry.SetSql("age < ? AND name = ?"); + qry.AddArgument<int>(20); + qry.AddArgument<std::string>("A1"); + + cursor = cache.Query(qry); + CheckSingle(cursor, 1, "A1", 10); + + cursor = cache.Query(qry); + CheckSingleGetAll(cursor, 1, "A1", 10); + + // Test query returning multiple entries. + qry = SqlQuery("QueryPerson", "age < 30"); + + cursor = cache.Query(qry); + CheckMultiple(cursor, 1, "A1", 10, 2, "A2", 20); + + cursor = cache.Query(qry); + CheckMultipleGetAll(cursor, 1, "A1", 10, 2, "A2", 20); +} + +/** + * Test text query. + */ +BOOST_AUTO_TEST_CASE(TestTextQuery) +{ + Cache<int, QueryPerson> cache = GetCache(); + + // Test query with no results. + TextQuery qry("QueryPerson", "A1"); + + QueryCursor<int, QueryPerson> cursor = cache.Query(qry); + CheckEmpty(cursor); + + cursor = cache.Query(qry); + CheckEmptyGetAll(cursor); + + // Test simple query. + cache.Put(1, QueryPerson("A1", 10)); + cache.Put(2, QueryPerson("A2", 20)); + + cursor = cache.Query(qry); + CheckSingle(cursor, 1, "A1", 10); + + cursor = cache.Query(qry); + CheckSingleGetAll(cursor, 1, "A1", 10); + + // Test simple local query. + qry.SetLocal(true); + + cursor = cache.Query(qry); + CheckSingle(cursor, 1, "A1", 10); + + cursor = cache.Query(qry); + CheckSingleGetAll(cursor, 1, "A1", 10); + + // Test query returning multiple entries. + qry = TextQuery("QueryPerson", "A*"); + + cursor = cache.Query(qry); + CheckMultiple(cursor, 1, "A1", 10, 2, "A2", 20); + + cursor = cache.Query(qry); + CheckMultipleGetAll(cursor, 1, "A1", 10, 2, "A2", 20); +} + +/** + * Test scan query. + */ +BOOST_AUTO_TEST_CASE(TestScanQuery) +{ + // Test simple query. + Cache<int, QueryPerson> cache = GetCache(); + + // Test query with no results. + ScanQuery qry; + + QueryCursor<int, QueryPerson> cursor = cache.Query(qry); + CheckEmpty(cursor); + + cursor = cache.Query(qry); + CheckEmptyGetAll(cursor); + + // Test simple query. + cache.Put(1, QueryPerson("A1", 10)); + + cursor = cache.Query(qry); + CheckSingle(cursor, 1, "A1", 10); + + cursor = cache.Query(qry); + CheckSingleGetAll(cursor, 1, "A1", 10); + + // Test query returning multiple entries. + cache.Put(2, QueryPerson("A2", 20)); + + cursor = cache.Query(qry); + CheckMultiple(cursor, 1, "A1", 10, 2, "A2", 20); + + cursor = cache.Query(qry); + CheckMultipleGetAll(cursor, 1, "A1", 10, 2, "A2", 20); +} + +/** + * Test scan query over partitions. + */ +BOOST_AUTO_TEST_CASE(TestScanQueryPartitioned) +{ + // Populate cache with data. + Cache<int, QueryPerson> cache = GetCache(); + + int32_t partCnt = 256; // Defined in configuration explicitly. + int32_t entryCnt = 1000; // Should be greater than partCnt. + + for (int i = 0; i < entryCnt; i++) + { + std::stringstream stream; + + stream << "A" << i; + + cache.Put(i, QueryPerson(stream.str(), i * 10)); + } + + // Iterate over all partitions and collect data. + std::set<int> keys; + + for (int i = 0; i < partCnt; i++) + { + ScanQuery qry(i); + + QueryCursor<int, QueryPerson> cur = cache.Query(qry); + + while (cur.HasNext()) + { + CacheEntry<int, QueryPerson> entry = cur.GetNext(); + + int key = entry.GetKey(); + + keys.insert(key); + + std::stringstream stream; + stream << "A" << key; + BOOST_REQUIRE(entry.GetValue().GetName().compare(stream.str()) == 0); + + BOOST_REQUIRE(entry.GetValue().GetAge() == key * 10); + } + } + + // Ensure that all keys were read. + BOOST_REQUIRE(keys.size() == entryCnt); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/58a665aa/modules/platform/src/main/cpp/core-test/src/cache_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/cpp/core-test/src/cache_test.cpp b/modules/platform/src/main/cpp/core-test/src/cache_test.cpp new file mode 100644 index 0000000..b69caab --- /dev/null +++ b/modules/platform/src/main/cpp/core-test/src/cache_test.cpp @@ -0,0 +1,481 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MSC_VER + #define BOOST_TEST_DYN_LINK +#endif + +#include <boost/test/unit_test.hpp> + +#include "ignite/cache/cache_peek_mode.h" +#include "ignite/ignite.h" +#include "ignite/ignition.h" + +using namespace ignite; +using namespace boost::unit_test; + +/* Nodes started during the test. */ +Ignite grid0 = Ignite(); +Ignite grid1 = Ignite(); + +/** Cache accessor. */ +cache::Cache<int, int> Cache() +{ + return grid0.GetCache<int, int>("partitioned"); +} + +struct Person +{ + std::string name; + int age; + + Person() : name(""), age(0) + { + // No-op. + } + + Person(std::string name, int age) : name(name), age(age) + { + // No-op. + } +}; + +namespace ignite +{ + namespace portable + { + IGNITE_PORTABLE_TYPE_START(Person) + IGNITE_PORTABLE_GET_TYPE_ID_AS_HASH(Person) + IGNITE_PORTABLE_GET_TYPE_NAME_AS_IS(Person) + IGNITE_PORTABLE_GET_FIELD_ID_AS_HASH + IGNITE_PORTABLE_GET_HASH_CODE_ZERO(Person) + IGNITE_PORTABLE_IS_NULL_FALSE(Person) + IGNITE_PORTABLE_GET_NULL_DEFAULT_CTOR(Person) + + void Write(PortableWriter& writer, Person obj) + { + writer.WriteString("name", obj.name); + writer.WriteInt32("age", obj.age); + } + + Person Read(PortableReader& reader) + { + std::string name = reader.ReadString("name"); + int age = reader.ReadInt32("age"); + + return Person(name, age); + } + + IGNITE_PORTABLE_TYPE_END + } +} + +/* + * Test setup fixture. + */ +struct CacheTestSuiteFixture { + /* + * Constructor. + */ + CacheTestSuiteFixture() + { + IgniteConfiguration cfg; + + IgniteJvmOption opts[5]; + + opts[0] = IgniteJvmOption("-Xdebug"); + opts[1] = IgniteJvmOption("-Xnoagent"); + opts[2] = IgniteJvmOption("-Djava.compiler=NONE"); + opts[3] = IgniteJvmOption("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"); + opts[4] = IgniteJvmOption("-XX:+HeapDumpOnOutOfMemoryError"); + + cfg.jvmOptsLen = 5; + cfg.jvmOpts = opts; + + cfg.jvmInitMem = 1024; + cfg.jvmMaxMem = 4096; + + char* cfgPath = getenv("IGNITE_NATIVE_TEST_CPP_CONFIG_PATH"); + + std::string cfgPathStr = std::string(cfgPath).append("/").append("cache-test.xml"); + + cfg.springCfgPath = const_cast<char*>(cfgPathStr.c_str()); + + for (int i = 0; i < 2; i++) + { + std::stringstream stream; + + stream << "grid-" << i; + + IgniteError err; + + Ignite grid = Ignition::Start(cfg, stream.str().c_str(), &err); + + if (err.GetCode() != IgniteError::IGNITE_SUCCESS) + BOOST_FAIL(err.GetText()); + + if (i == 0) + grid0 = grid; + else + grid1 = grid; + } + } + + /* + * Destructor. + */ + ~CacheTestSuiteFixture() + { + Ignition::Stop(grid0.GetName(), true); + Ignition::Stop(grid1.GetName(), true); + + grid0 = Ignite(); + grid1 = Ignite(); + } +}; + +BOOST_FIXTURE_TEST_SUITE(CacheTestSuite, CacheTestSuiteFixture) + +BOOST_AUTO_TEST_CASE(TestRemoveAllKeys) +{ + cache::Cache<int, int> cache = Cache(); + + cache.Put(1, 1); + cache.Put(2, 2); + cache.Put(3, 3); + + int size = cache.Size(cache::IGNITE_PEEK_MODE_PRIMARY); + + BOOST_REQUIRE(3 == size); + + cache.RemoveAll(); + + size = cache.Size(cache::IGNITE_PEEK_MODE_ALL); + + BOOST_REQUIRE(0 == size); + + cache.Put(1, 1); + cache.Put(2, 2); + cache.Put(3, 3); + + int keys[] = { 1, 2, 4, 5 }; + + std::set<int> keySet(keys, keys + 4); + + cache.RemoveAll(keySet); + + size = cache.Size(cache::IGNITE_PEEK_MODE_PRIMARY); + + BOOST_REQUIRE(1 == size); +} + +BOOST_AUTO_TEST_CASE(TestPut) +{ + cache::Cache<int, int> cache = Cache(); + + cache.Put(1, 1); + + BOOST_REQUIRE(1 == cache.Get(1)); +} + +BOOST_AUTO_TEST_CASE(TestPutAll) +{ + std::map<int, int> map; + + for (int i = 0; i < 100; i++) + map[i] = i + 1; + + cache::Cache<int, int> cache = Cache(); + + cache.PutAll(map); + + for (int i = 0; i < 100; i++) + BOOST_REQUIRE(i + 1 == cache.Get(i)); +} + +BOOST_AUTO_TEST_CASE(TestPutIfAbsent) +{ + cache::Cache<int, int> cache = Cache(); + + BOOST_REQUIRE(true == cache.PutIfAbsent(1, 3)); + BOOST_REQUIRE(false == cache.PutIfAbsent(1, 3)); +} + +BOOST_AUTO_TEST_CASE(TestGet) +{ + cache::Cache<int, int> cache = Cache(); + + cache.Put(1, 1); + cache.Put(2, 2); + + BOOST_REQUIRE(1 == cache.Get(1)); + BOOST_REQUIRE(2 == cache.Get(2)); + + BOOST_REQUIRE(0 == cache.Get(3)); +} + +BOOST_AUTO_TEST_CASE(TestGetAll) +{ + cache::Cache<int, int> cache = Cache(); + + int keys[] = { 1, 2, 3, 4, 5 }; + + std::set<int> keySet (keys, keys + 5); + + for (int i = 0; i < keySet.size(); i++) + cache.Put(i + 1, i + 1); + + std::map<int, int> map = cache.GetAll(keySet); + + for (int i = 0; i < keySet.size(); i++) + BOOST_REQUIRE(i + 1 == map[i + 1]); +} + +BOOST_AUTO_TEST_CASE(TestGetAndPut) +{ + cache::Cache<int, int> cache = Cache(); + + BOOST_REQUIRE(0 == cache.GetAndPut(1, 3)); + BOOST_REQUIRE(3 == cache.GetAndPut(1, 1)); + BOOST_REQUIRE(1 == cache.GetAndPut(1, 0)); +} + +BOOST_AUTO_TEST_CASE(TestGetAndPutIfAbsent) +{ + cache::Cache<int, int> cache = Cache(); + + BOOST_REQUIRE(0 == cache.GetAndPutIfAbsent(1, 3)); + BOOST_REQUIRE(3 == cache.GetAndPutIfAbsent(1, 1)); + BOOST_REQUIRE(3 == cache.GetAndPutIfAbsent(1, 1)); +} + +BOOST_AUTO_TEST_CASE(TestGetAndRemove) +{ + cache::Cache<int, int> cache = Cache(); + + cache.Put(1, 3); + + BOOST_REQUIRE(3 == cache.GetAndRemove(1)); + BOOST_REQUIRE(0 == cache.GetAndRemove(1)); +} + +BOOST_AUTO_TEST_CASE(TestGetAndReplace) +{ + cache::Cache<int, int> cache = Cache(); + + BOOST_REQUIRE(0 == cache.GetAndReplace(1, 3)); + BOOST_REQUIRE(0 == cache.GetAndReplace(1, 3)); + + cache.Put(1, 5); + + BOOST_REQUIRE(5 == cache.GetAndReplace(1, 3)); + BOOST_REQUIRE(3 == cache.GetAndReplace(1, 3)); +} + +BOOST_AUTO_TEST_CASE(TestContainsKey) +{ + cache::Cache<int, int> cache = Cache(); + + BOOST_REQUIRE(false == cache.ContainsKey(1)); + + cache.Put(1, 1); + + BOOST_REQUIRE(true == cache.ContainsKey(1)); + + BOOST_REQUIRE(true == cache.Remove(1)); + + BOOST_REQUIRE(false == cache.ContainsKey(1)); +} + +BOOST_AUTO_TEST_CASE(TestContainsKeys) +{ + cache::Cache<int, int> cache = Cache(); + + int keys[] = { 1, 2 }; + + std::set<int> keySet(keys, keys + 2); + + BOOST_REQUIRE(false == cache.ContainsKeys(keySet)); + + cache.Put(1, 1); + cache.Put(2, 2); + + BOOST_REQUIRE(true == cache.ContainsKeys(keySet)); + + cache.Remove(1); + + BOOST_REQUIRE(false == cache.ContainsKeys(keySet)); +} + +BOOST_AUTO_TEST_CASE(TestIsEmpty) +{ + cache::Cache<int, int> cache = Cache(); + + BOOST_REQUIRE(true == cache.IsEmpty()); + + cache.Put(1, 1); + + BOOST_REQUIRE(false == cache.IsEmpty()); + + cache.Remove(1); + + BOOST_REQUIRE(true == cache.IsEmpty()); +} + +BOOST_AUTO_TEST_CASE(TestRemove) +{ + cache::Cache<int, int> cache = Cache(); + + BOOST_REQUIRE(false == cache.Remove(1)); + + cache.Put(1, 1); + + BOOST_REQUIRE(true == cache.Remove(1)); + BOOST_REQUIRE(false == cache.Remove(1)); + BOOST_REQUIRE(false == cache.ContainsKey(1)); +} + +BOOST_AUTO_TEST_CASE(TestClear) +{ + cache::Cache<int, int> cache = Cache(); + + cache.Put(1, 1); + + BOOST_REQUIRE(true == cache.ContainsKey(1)); + + cache.Clear(1); + + BOOST_REQUIRE(false == cache.ContainsKey(1)); +} + +BOOST_AUTO_TEST_CASE(TestLocalClear) +{ + cache::Cache<int, int> cache = Cache(); + + cache.Put(0, 2); + + BOOST_REQUIRE(2 == cache.LocalPeek(0, cache::IGNITE_PEEK_MODE_PRIMARY)); + + cache.LocalClear(0); + + BOOST_REQUIRE(0 == cache.LocalPeek(0, cache::IGNITE_PEEK_MODE_PRIMARY)); +} + +BOOST_AUTO_TEST_CASE(TestLocalClearAll) +{ + cache::Cache<int, int> cache = Cache(); + + cache.Put(0, 3); + cache.Put(1, 3); + + int keys[] = { 0, 1 }; + + std::set<int> keySet(keys, keys + 2); + + BOOST_REQUIRE(3 == cache.LocalPeek(0, cache::IGNITE_PEEK_MODE_PRIMARY)); + BOOST_REQUIRE(3 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_PRIMARY)); + + cache.LocalClearAll(keySet); + + BOOST_REQUIRE(0 == cache.LocalPeek(0, cache::IGNITE_PEEK_MODE_PRIMARY)); + BOOST_REQUIRE(0 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_PRIMARY)); +} + +BOOST_AUTO_TEST_CASE(TestSizes) +{ + cache::Cache<int, int> cache = Cache(); + + BOOST_REQUIRE(0 == cache.Size()); + + cache.Put(1, 1); + cache.Put(2, 2); + + BOOST_REQUIRE(2 <= cache.Size()); + + BOOST_REQUIRE(1 <= cache.LocalSize(cache::IGNITE_PEEK_MODE_PRIMARY)); +} + +BOOST_AUTO_TEST_CASE(TestLocalEvict) +{ + cache::Cache<int, int> cache = Cache(); + + cache.Put(1, 5); + + BOOST_REQUIRE(5 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_ONHEAP)); + + int keys[] = { 0, 1 }; + + std::set<int> keySet(keys, keys + 2); + + cache.LocalEvict(keySet); + + BOOST_REQUIRE(0 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_ONHEAP)); + + BOOST_REQUIRE(5 == cache.Get(1)); + + BOOST_REQUIRE(5 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_ONHEAP)); +} + +BOOST_AUTO_TEST_CASE(TestPortable) +{ + cache::Cache<int, Person> cache = grid0.GetCache<int, Person>("partitioned"); + + Person person("John Johnson", 3); + + cache.Put(1, person); + + Person person0 = cache.Get(1); + + BOOST_REQUIRE(person.age == person0.age); + BOOST_REQUIRE(person.name.compare(person0.name) == 0); +} + +BOOST_AUTO_TEST_CASE(TestCreateCache) +{ + // Create new cache + cache::Cache<int, int> cache = grid0.CreateCache<int, int>("dynamic_cache"); + + cache.Put(5, 7); + + BOOST_REQUIRE(7 == cache.Get(5)); + + // Attempt to create cache with existing name + IgniteError err; + + grid0.CreateCache<int, int>("dynamic_cache", &err); + + BOOST_REQUIRE(err.GetCode() != IgniteError::IGNITE_SUCCESS); +} + +BOOST_AUTO_TEST_CASE(TestGetOrCreateCache) +{ + // Get existing cache + cache::Cache<int, int> cache = grid0.GetOrCreateCache<int, int>("partitioned"); + + cache.Put(5, 7); + + BOOST_REQUIRE(7 == cache.Get(5)); + + // Create new cache + cache::Cache<int, int> cache2 = grid0.GetOrCreateCache<int, int>("partitioned_new"); + + cache2.Put(5, 7); + + BOOST_REQUIRE(7 == cache2.Get(5)); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/58a665aa/modules/platform/src/main/cpp/core-test/src/concurrent_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/cpp/core-test/src/concurrent_test.cpp b/modules/platform/src/main/cpp/core-test/src/concurrent_test.cpp new file mode 100644 index 0000000..2d89b7a --- /dev/null +++ b/modules/platform/src/main/cpp/core-test/src/concurrent_test.cpp @@ -0,0 +1,186 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MSC_VER + #define BOOST_TEST_DYN_LINK +#endif + +#include <boost/test/unit_test.hpp> + +#include <ignite/common/concurrent.h> + +using namespace ignite::common::concurrent; + +BOOST_AUTO_TEST_SUITE(ConcurrentTestSuite) + +BOOST_AUTO_TEST_CASE(TestAtomic32) +{ + int32_t val = 1; + + BOOST_REQUIRE(Atomics::CompareAndSet32(&val, 1, 2)); + BOOST_REQUIRE(val == 2); + + BOOST_REQUIRE(!Atomics::CompareAndSet32(&val, 3, 1)); + BOOST_REQUIRE(val == 2); + + BOOST_REQUIRE(Atomics::CompareAndSet32Val(&val, 2, 3) == 2); + BOOST_REQUIRE(val == 3); + + BOOST_REQUIRE(Atomics::CompareAndSet32Val(&val, 4, 2) == 3); + BOOST_REQUIRE(val == 3); + + BOOST_REQUIRE(Atomics::IncrementAndGet32(&val) == 4); + BOOST_REQUIRE(val == 4); + + BOOST_REQUIRE(Atomics::DecrementAndGet32(&val) == 3); + BOOST_REQUIRE(val == 3); +} + +BOOST_AUTO_TEST_CASE(TestAtomic64) +{ + int64_t val = 1; + + BOOST_REQUIRE(Atomics::CompareAndSet64(&val, 1, 2)); + BOOST_REQUIRE(val == 2); + + BOOST_REQUIRE(!Atomics::CompareAndSet64(&val, 3, 1)); + BOOST_REQUIRE(val == 2); + + BOOST_REQUIRE(Atomics::CompareAndSet64Val(&val, 2, 3) == 2); + BOOST_REQUIRE(val == 3); + + BOOST_REQUIRE(Atomics::CompareAndSet64Val(&val, 4, 2) == 3); + BOOST_REQUIRE(val == 3); + + BOOST_REQUIRE(Atomics::IncrementAndGet64(&val) == 4); + BOOST_REQUIRE(val == 4); + + BOOST_REQUIRE(Atomics::DecrementAndGet64(&val) == 3); + BOOST_REQUIRE(val == 3); +} + +BOOST_AUTO_TEST_CASE(TestThreadLocal) +{ + int32_t idx1 = ThreadLocal::NextIndex(); + int32_t idx2 = ThreadLocal::NextIndex(); + BOOST_REQUIRE(idx2 > idx1); + + BOOST_REQUIRE(ThreadLocal::Get<int32_t>(idx1) == 0); + + ThreadLocal::Set(idx1, 1); + BOOST_REQUIRE(ThreadLocal::Get<int32_t>(idx1) == 1); + + ThreadLocal::Set(idx1, 2); + BOOST_REQUIRE(ThreadLocal::Get<int32_t>(idx1) == 2); + + ThreadLocal::Remove(idx1); + BOOST_REQUIRE(ThreadLocal::Get<int32_t>(idx1) == 0); + + ThreadLocal::Set(idx1, 1); + BOOST_REQUIRE(ThreadLocal::Get<int32_t>(idx1) == 1); + + ThreadLocal::Remove(idx1); +} + +BOOST_AUTO_TEST_CASE(TestThreadLocalInstance) +{ + ThreadLocalInstance<int32_t> val; + + BOOST_REQUIRE(val.Get() == 0); + + val.Set(1); + BOOST_REQUIRE(val.Get() == 1); + + val.Set(2); + BOOST_REQUIRE(val.Get() == 2); + + val.Remove(); + BOOST_REQUIRE(val.Get() == 0); + + val.Set(1); + BOOST_REQUIRE(val.Get() == 1); + + val.Remove(); +} + +struct SharedPointerTarget +{ + bool deleted; + + SharedPointerTarget() : deleted(false) + { + // No-op. + } +}; + +void DeleteSharedPointerTarget(SharedPointerTarget* ptr) +{ + ptr->deleted = true; +} + +BOOST_AUTO_TEST_CASE(TestSharedPointer) +{ + // 1. Test the simples scenario. + SharedPointerTarget* target = new SharedPointerTarget(); + + SharedPointer<SharedPointerTarget>* ptr1 = + new SharedPointer<SharedPointerTarget>(target, DeleteSharedPointerTarget); + + delete ptr1; + BOOST_REQUIRE(target->deleted); + + target->deleted = false; + + // 2. Test copy ctor. + ptr1 = new SharedPointer<SharedPointerTarget>(target, DeleteSharedPointerTarget); + SharedPointer<SharedPointerTarget>* ptr2 = new SharedPointer<SharedPointerTarget>(*ptr1); + + delete ptr1; + BOOST_REQUIRE(!target->deleted); + + delete ptr2; + BOOST_REQUIRE(target->deleted); + + target->deleted = false; + + // 3. Test assignment logic. + ptr1 = new SharedPointer<SharedPointerTarget>(target, DeleteSharedPointerTarget); + + SharedPointer<SharedPointerTarget> ptr3 = *ptr1; + + delete ptr1; + BOOST_REQUIRE(!target->deleted); + + ptr3 = SharedPointer<SharedPointerTarget>(); + BOOST_REQUIRE(target->deleted); + + target->deleted = false; + + // 4. Test self-assignment. + ptr1 = new SharedPointer<SharedPointerTarget>(target, DeleteSharedPointerTarget); + + *ptr1 = *ptr1; + + delete ptr1; + + BOOST_REQUIRE(target->deleted); + + // 5. Tear-down. + delete target; +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/58a665aa/modules/platform/src/main/cpp/core-test/src/handle_registry_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/cpp/core-test/src/handle_registry_test.cpp b/modules/platform/src/main/cpp/core-test/src/handle_registry_test.cpp new file mode 100644 index 0000000..bc4a654 --- /dev/null +++ b/modules/platform/src/main/cpp/core-test/src/handle_registry_test.cpp @@ -0,0 +1,176 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MSC_VER + #define BOOST_TEST_DYN_LINK +#endif + +#include <boost/test/unit_test.hpp> + +#include "ignite/impl/handle_registry.h" + +using namespace ignite::common::concurrent; +using namespace ignite::impl; + +struct HandleRegistryTestProbe +{ + bool deleted; + + HandleRegistryTestProbe() + { + deleted = false; + } +}; + +class HandleRegistryTestEntry : public HandleRegistryEntry +{ +public: + HandleRegistryTestEntry(HandleRegistryTestProbe* probe) : probe(probe) + { + // No-op. + } + + virtual ~HandleRegistryTestEntry() + { + probe->deleted = true; + } + +private: + HandleRegistryTestProbe* probe; +}; + +BOOST_AUTO_TEST_SUITE(HandleRegistryTestSuite) + +BOOST_AUTO_TEST_CASE(TestCritical) +{ + HandleRegistry reg(2, 1); + + HandleRegistryTestProbe probe0; + HandleRegistryTestProbe probe1; + HandleRegistryTestProbe probe2; + + HandleRegistryTestEntry* entry0 = new HandleRegistryTestEntry(&probe0); + HandleRegistryTestEntry* entry1 = new HandleRegistryTestEntry(&probe1); + HandleRegistryTestEntry* entry2 = new HandleRegistryTestEntry(&probe2); + + int64_t hnd0 = reg.AllocateCritical(SharedPointer<HandleRegistryEntry>(entry0)); + int64_t hnd1 = reg.AllocateCritical(SharedPointer<HandleRegistryEntry>(entry1)); + int64_t hnd2 = reg.AllocateCritical(SharedPointer<HandleRegistryEntry>(entry2)); + + BOOST_REQUIRE(reg.Get(hnd0).Get() == entry0); + BOOST_REQUIRE(!probe0.deleted); + + BOOST_REQUIRE(reg.Get(hnd1).Get() == entry1); + BOOST_REQUIRE(!probe1.deleted); + + BOOST_REQUIRE(reg.Get(hnd2).Get() == entry2); + BOOST_REQUIRE(!probe2.deleted); + + reg.Release(hnd0); + + BOOST_REQUIRE(reg.Get(hnd0).Get() == NULL); + BOOST_REQUIRE(probe0.deleted); + + BOOST_REQUIRE(reg.Get(hnd1).Get() == entry1); + BOOST_REQUIRE(!probe1.deleted); + + BOOST_REQUIRE(reg.Get(hnd2).Get() == entry2); + BOOST_REQUIRE(!probe2.deleted); + + reg.Close(); + + BOOST_REQUIRE(reg.Get(hnd0).Get() == NULL); + BOOST_REQUIRE(probe0.deleted); + + BOOST_REQUIRE(reg.Get(hnd1).Get() == NULL); + BOOST_REQUIRE(probe1.deleted); + + BOOST_REQUIRE(reg.Get(hnd2).Get() == NULL); + BOOST_REQUIRE(probe2.deleted); + + HandleRegistry closedReg(2, 1); + + closedReg.Close(); + + HandleRegistryTestProbe closedProbe; + HandleRegistryTestEntry* closedEntry = new HandleRegistryTestEntry(&closedProbe); + + int64_t closedHnd = closedReg.AllocateCritical(SharedPointer<HandleRegistryEntry>(closedEntry)); + BOOST_REQUIRE(closedHnd == -1); + BOOST_REQUIRE(closedProbe.deleted); +} + +BOOST_AUTO_TEST_CASE(TestNonCritical) +{ + HandleRegistry reg(0, 2); + + HandleRegistryTestProbe probe0; + HandleRegistryTestProbe probe1; + HandleRegistryTestProbe probe2; + + HandleRegistryTestEntry* entry0 = new HandleRegistryTestEntry(&probe0); + HandleRegistryTestEntry* entry1 = new HandleRegistryTestEntry(&probe1); + HandleRegistryTestEntry* entry2 = new HandleRegistryTestEntry(&probe2); + + int64_t hnd0 = reg.AllocateCritical(SharedPointer<HandleRegistryEntry>(entry0)); + int64_t hnd1 = reg.Allocate(SharedPointer<HandleRegistryEntry>(entry1)); + int64_t hnd2 = reg.Allocate(SharedPointer<HandleRegistryEntry>(entry2)); + + BOOST_REQUIRE(reg.Get(hnd0).Get() == entry0); + BOOST_REQUIRE(!probe0.deleted); + + BOOST_REQUIRE(reg.Get(hnd1).Get() == entry1); + BOOST_REQUIRE(!probe1.deleted); + + BOOST_REQUIRE(reg.Get(hnd2).Get() == entry2); + BOOST_REQUIRE(!probe2.deleted); + + reg.Release(hnd0); + + BOOST_REQUIRE(reg.Get(hnd0).Get() == NULL); + BOOST_REQUIRE(probe0.deleted); + + BOOST_REQUIRE(reg.Get(hnd1).Get() == entry1); + BOOST_REQUIRE(!probe1.deleted); + + BOOST_REQUIRE(reg.Get(hnd2).Get() == entry2); + BOOST_REQUIRE(!probe2.deleted); + + reg.Close(); + + BOOST_REQUIRE(reg.Get(hnd0).Get() == NULL); + BOOST_REQUIRE(probe0.deleted); + + BOOST_REQUIRE(reg.Get(hnd1).Get() == NULL); + BOOST_REQUIRE(probe1.deleted); + + BOOST_REQUIRE(reg.Get(hnd2).Get() == NULL); + BOOST_REQUIRE(probe2.deleted); + + HandleRegistry closedReg(0, 2); + + closedReg.Close(); + + HandleRegistryTestProbe closedProbe; + HandleRegistryTestEntry* closedEntry = new HandleRegistryTestEntry(&closedProbe); + + int64_t closedHnd = closedReg.Allocate(SharedPointer<HandleRegistryEntry>(closedEntry)); + BOOST_REQUIRE(closedHnd == -1); + BOOST_REQUIRE(closedProbe.deleted); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/58a665aa/modules/platform/src/main/cpp/core-test/src/ignition_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/cpp/core-test/src/ignition_test.cpp b/modules/platform/src/main/cpp/core-test/src/ignition_test.cpp new file mode 100644 index 0000000..f55977a --- /dev/null +++ b/modules/platform/src/main/cpp/core-test/src/ignition_test.cpp @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MSC_VER + #define BOOST_TEST_DYN_LINK +#endif + +#include <boost/test/unit_test.hpp> + +#include "ignite/ignite.h" +#include "ignite/ignition.h" + +using namespace ignite; +using namespace boost::unit_test; + +BOOST_AUTO_TEST_SUITE(IgnitionTestSuite) + +BOOST_AUTO_TEST_CASE(TestIgnition) +{ + IgniteConfiguration cfg; + + IgniteJvmOption opts[5]; + + opts[0] = IgniteJvmOption("-Xdebug"); + opts[1] = IgniteJvmOption("-Xnoagent"); + opts[2] = IgniteJvmOption("-Djava.compiler=NONE"); + opts[3] = IgniteJvmOption("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"); + opts[4] = IgniteJvmOption("-XX:+HeapDumpOnOutOfMemoryError"); + + cfg.jvmOptsLen = 5; + cfg.jvmOpts = opts; + + cfg.jvmInitMem = 1024; + cfg.jvmMaxMem = 4096; + + char* cfgPath = getenv("IGNITE_NATIVE_TEST_CPP_CONFIG_PATH"); + + std::string cfgPathStr = std::string(cfgPath).append("/").append("cache-test.xml"); + + cfg.springCfgPath = const_cast<char*>(cfgPathStr.c_str()); + + IgniteError err; + + // Start two Ignite instances. + Ignite grid1 = Ignition::Start(cfg, "ignitionTest-1", &err); + + if (err.GetCode() != IgniteError::IGNITE_SUCCESS) + BOOST_ERROR(err.GetText()); + + BOOST_REQUIRE(strcmp(grid1.GetName(), "ignitionTest-1") == 0); + + Ignite grid2 = Ignition::Start(cfg, "ignitionTest-2", &err); + + if (err.GetCode() != IgniteError::IGNITE_SUCCESS) + BOOST_ERROR(err.GetText()); + + BOOST_REQUIRE(strcmp(grid2.GetName(), "ignitionTest-2") == 0); + + // Test get + Ignite grid0 = Ignition::Get("ignitionTest-1", &err); + + if (err.GetCode() != IgniteError::IGNITE_SUCCESS) + BOOST_ERROR(err.GetText()); + + BOOST_REQUIRE(strcmp(grid0.GetName(), grid1.GetName()) == 0); + + // Stop one grid + Ignition::Stop(grid1.GetName(), true); + + Ignition::Get("ignitionTest-1", &err); + BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_GENERIC); + + Ignition::Get("ignitionTest-2", &err); + BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_SUCCESS); + + // Stop all + Ignition::StopAll(true); + + Ignition::Get("ignitionTest-2", &err); + BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_GENERIC); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file
