blob: 37a3a0d0cd5ecf07ca2fa888d2b976926853a5e6 [file] [log] [blame]
/*
* 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.
*/
#include <boost/test/unit_test.hpp>
#include <ignite/common/utils.h>
#include <ignite/common/fixed_size_array.h>
#include <ignite/binary/binary_object.h>
#include <ignite/binary/binary_writer.h>
#include <ignite/binary/binary_enum.h>
#include <ignite/binary/binary_enum_entry.h>
#include <ignite/ignition.h>
#include "ignite/binary_test_defs.h"
#include "ignite/test_type.h"
#include "ignite/complex_type.h"
#include "ignite/test_utils.h"
using namespace ignite;
using namespace ignite::binary;
using namespace ignite::impl::interop;
using namespace ignite::impl::binary;
using namespace ignite_test::core::binary;
template<typename T>
void FillMem(InteropMemory& mem, const T& value)
{
InteropOutputStream stream(&mem);
BinaryWriterImpl writer(&stream, 0);
writer.WriteObject<T>(value);
stream.Synchronize();
}
template<typename T>
void CheckSimple(const T& value)
{
InteropUnpooledMemory mem(1024);
FillMem<T>(mem, value);
BinaryObject obj(BinaryObjectImpl::FromMemory(mem, 0, 0));
T actual = obj.Deserialize<T>();
BOOST_REQUIRE_EQUAL(value, actual);
}
template<typename T>
void CheckSimpleNP(const T& value)
{
InteropUnpooledMemory mem(1024);
FillMem<T>(mem, value);
BinaryObject obj(BinaryObjectImpl::FromMemory(mem, 0, 0));
T actual = obj.Deserialize<T>();
BOOST_REQUIRE(value == actual);
}
template<typename T>
void GetObjectData(const T& obj, common::FixedSizeArray<int8_t>& data)
{
DummyIdResolver idResolver;
InteropUnpooledMemory mem(1024);
InteropOutputStream stream(&mem);
BinaryWriterImpl writerImpl(&stream, &idResolver, 0, 0, 0);
BinaryWriter writer(&writerImpl);
BinaryType<T>::Write(writer, obj);
data.Assign(mem.Data(), stream.Position());
}
template<typename T>
void CheckData(const T& obj)
{
common::FixedSizeArray<int8_t> objData;
GetObjectData<T>(obj, objData);
InteropUnpooledMemory mem(1024);
FillMem<T>(mem, obj);
BinaryObjectImpl binObj(BinaryObjectImpl::FromMemory(mem, 0, 0));
BOOST_REQUIRE_EQUAL(binObj.GetLength(), objData.GetSize());
common::FixedSizeArray<int8_t> binObjData(binObj.GetData(), binObj.GetLength());
for (int32_t i = 0; i < objData.GetSize(); ++i)
BOOST_CHECK_EQUAL(objData[i], binObjData[i]);
}
template<typename F, typename T>
void CheckField(const T& obj, const char* field, const F& expected)
{
InteropUnpooledMemory mem(1024);
FillMem<T>(mem, obj);
TemplatedBinaryIdResolver<T> resolver;
BinaryObject binObj(mem, 0, &resolver, 0);
BOOST_REQUIRE(binObj.HasField(field));
F actual = binObj.GetField<F>(field);
BOOST_CHECK_EQUAL(actual, expected);
}
template<typename F, typename T>
void CheckFieldNP(const T& obj, const char* field, const F& expected)
{
InteropUnpooledMemory mem(1024);
FillMem<T>(mem, obj);
TemplatedBinaryIdResolver<T> resolver;
BinaryObject binObj(mem, 0, &resolver, 0);
BOOST_REQUIRE(binObj.HasField(field));
F actual = binObj.GetField<F>(field);
BOOST_CHECK(actual == expected);
}
template<typename T>
void CheckNoField(const T& obj, const char* field)
{
InteropUnpooledMemory mem(1024);
FillMem<T>(mem, obj);
TemplatedBinaryIdResolver<T> resolver;
BinaryObject binObj(mem, 0, &resolver, 0);
BOOST_REQUIRE(!binObj.HasField(field));
}
BOOST_AUTO_TEST_SUITE(BinaryObjectTestSuite)
BOOST_AUTO_TEST_CASE(UserTestType)
{
CheckSimpleNP(TestType());
CheckSimpleNP(TestType(1, 2, 3, 4, "5", 6.0f, 7.0, true, Guid(8, 9),
common::MakeDateGmt(1987, 6, 5),
common::MakeTimeGmt(13, 32, 9),
common::MakeTimestampGmt(1998, 12, 27, 1, 2, 3, 456)));
}
BOOST_AUTO_TEST_CASE(UserComplexType)
{
CheckSimpleNP(ComplexType());
ComplexType nonDefault;
nonDefault.i32Field = 589630659;
nonDefault.strField = "Some string value";
nonDefault.objField.f1 = 403685016;
nonDefault.objField.f2 = "Whatever";
CheckSimpleNP(nonDefault);
}
BOOST_AUTO_TEST_CASE(UserBinaryFields)
{
CheckSimpleNP(BinaryFields());
BinaryFields nonDefault(423425, 961851, 18946, 180269165);
CheckSimpleNP(nonDefault);
}
BOOST_AUTO_TEST_CASE(UserComplexTypeGetData)
{
CheckData(ComplexType());
ComplexType nonDefault;
nonDefault.i32Field = 589630659;
nonDefault.strField = "Some string value";
nonDefault.objField.f1 = 403685016;
nonDefault.objField.f2 = "Whatever";
CheckData(nonDefault);
}
BOOST_AUTO_TEST_CASE(UserTestTypeGetData)
{
CheckData(TestType());
CheckData(TestType(1, 2, 3, 4, "5", 6.0f, 7.0, true, Guid(8, 9),
common::MakeDateGmt(1987, 6, 5),
common::MakeTimeGmt(13, 32, 9),
common::MakeTimestampGmt(1998, 12, 27, 1, 2, 3, 456)));
}
BOOST_AUTO_TEST_CASE(UserBinaryFieldsGetData)
{
CheckData(BinaryFields());
CheckData(BinaryFields(423425, 961851, 18946, 180269165));
}
BOOST_AUTO_TEST_CASE(UserBinaryFieldsGetField)
{
BinaryFields dflt;
CheckField<int32_t>(dflt, "val1", dflt.val1);
CheckField<int32_t>(dflt, "val2", dflt.val2);
CheckNoField(dflt, "rawVal1");
CheckNoField(dflt, "rawVal2");
CheckNoField(dflt, "some");
CheckNoField(dflt, "unknown");
CheckNoField(dflt, "");
BinaryFields some(423425, 961851, 18946, 180269165);
CheckField<int32_t>(some, "val1", some.val1);
CheckField<int32_t>(some, "val2", some.val2);
CheckNoField(some, "rawVal1");
CheckNoField(some, "rawVal2");
CheckNoField(some, "some");
CheckNoField(some, "unknown");
CheckNoField(some, "");
}
BOOST_AUTO_TEST_CASE(UserTestTypeGetField)
{
TestType dflt;
CheckField<int8_t>(dflt, "i8Field", dflt.i8Field);
CheckField<int16_t>(dflt, "i16Field", dflt.i16Field);
CheckField<int32_t>(dflt, "i32Field", dflt.i32Field);
CheckField<int64_t>(dflt, "i64Field", dflt.i64Field);
CheckField<std::string>(dflt, "strField", dflt.strField);
CheckField<float>(dflt, "floatField", dflt.floatField);
CheckField<double>(dflt, "doubleField", dflt.doubleField);
CheckField<bool>(dflt, "boolField", dflt.boolField);
CheckField<Guid>(dflt, "guidField", dflt.guidField);
CheckFieldNP<Date>(dflt, "dateField", dflt.dateField);
CheckFieldNP<Time>(dflt, "timeField", dflt.timeField);
CheckFieldNP<Timestamp>(dflt, "timestampField", dflt.timestampField);
CheckNoField(dflt, "some");
CheckNoField(dflt, "unknown");
CheckNoField(dflt, "");
TestType some(31, 2314, 54363467, -534180269165, "Lorem ipsum", 45364.46462f, 0.0750732, true,
Guid(8934658962, 56784598325), common::MakeDateGmt(1997, 3, 21), common::MakeTimeGmt(23, 50, 11),
common::MakeTimestampGmt(2002, 4, 12, 14, 36, 29, 438576348));
CheckField<int8_t>(some, "i8Field", some.i8Field);
CheckField<int16_t>(some, "i16Field", some.i16Field);
CheckField<int32_t>(some, "i32Field", some.i32Field);
CheckField<int64_t>(some, "i64Field", some.i64Field);
CheckField<std::string>(some, "strField", some.strField);
CheckField<float>(some, "floatField", some.floatField);
CheckField<double>(some, "doubleField", some.doubleField);
CheckField<bool>(some, "boolField", some.boolField);
CheckField<Guid>(some, "guidField", some.guidField);
CheckFieldNP<Date>(some, "dateField", some.dateField);
CheckFieldNP<Time>(some, "timeField", some.timeField);
CheckFieldNP<Timestamp>(some, "timestampField", some.timestampField);
CheckNoField(some, "some");
CheckNoField(some, "unknown");
CheckNoField(some, "");
}
BOOST_AUTO_TEST_CASE(UserBinaryOuterGetField)
{
BinaryOuter some(1895298, 592856);
InteropUnpooledMemory mem(1024);
FillMem(mem, some);
TemplatedBinaryIdResolver<BinaryOuter> resolver;
BinaryObject binObj(mem, 0, &resolver, 0);
BOOST_REQUIRE(binObj.HasField("val"));
BOOST_REQUIRE(binObj.HasField("inner"));
int32_t outer = binObj.GetField<int32_t>("val");
BinaryObject inner = binObj.GetField<BinaryObject>("inner");
BOOST_CHECK_EQUAL(outer, some.GetValue());
}
BOOST_AUTO_TEST_CASE(ExceptionSafety)
{
BinaryFields some(43956293, 567894632, 253945, 107576622);
InteropUnpooledMemory mem(1024);
FillMem(mem, some);
TemplatedBinaryIdResolver<BinaryOuter> resolver;
BinaryObject binObj(mem, 0, &resolver, 0);
BOOST_CHECK_THROW(binObj.Deserialize<TestType>(), IgniteError);
BinaryFields restored = binObj.Deserialize<BinaryFields>();
BOOST_CHECK(restored == some);
}
BOOST_AUTO_TEST_CASE(RemoteSchemaRetrieval)
{
try
{
BOOST_TEST_CHECKPOINT("Node1 startup");
#ifdef IGNITE_TESTS_32
Ignite node1 = ignite_test::StartNode("cache-test-32.xml", "node1");
#else
Ignite node1 = ignite_test::StartNode("cache-test.xml", "node1");
#endif
BOOST_TEST_CHECKPOINT("Creating cache");
cache::Cache<int32_t, BinaryFields> cache = node1.GetOrCreateCache<int32_t, BinaryFields>("cache");
BinaryFields some(25675472, 67461, 457542, 87073456);
BOOST_TEST_CHECKPOINT("Putting value");
cache.Put(42, some);
BOOST_TEST_CHECKPOINT("Node2 startup");
#ifdef IGNITE_TESTS_32
Ignite node2 = ignite_test::StartNode("cache-test-32.xml", "node2");
#else
Ignite node2 = ignite_test::StartNode("cache-test.xml", "node2");
#endif
impl::IgniteImpl* nodeImpl = impl::IgniteImpl::GetFromProxy(node2);
impl::IgniteEnvironment* env = nodeImpl->GetEnvironment();
InteropUnpooledMemory mem(1024);
FillMem<BinaryFields>(mem, some);
BOOST_TEST_CHECKPOINT("Creating BinaryObject");
BinaryObject binObj(mem, 0, 0, env->GetTypeManager());
BOOST_CHECK(binObj.HasField("val1"));
BOOST_CHECK(binObj.HasField("val2"));
int32_t val1 = binObj.GetField<int32_t>("val1");
int32_t val2 = binObj.GetField<int32_t>("val2");
BOOST_CHECK_EQUAL(val1, some.val1);
BOOST_CHECK_EQUAL(val2, some.val2);
BOOST_CHECK(!binObj.HasField("rawVal1"));
BOOST_CHECK(!binObj.HasField("rawVal2"));
BOOST_CHECK(!binObj.HasField("some"));
BOOST_CHECK(!binObj.HasField("unknown"));
BOOST_CHECK(!binObj.HasField("some_really_long_and_FancyName32047_20567934065286584067325693462"));
}
catch (...)
{
Ignition::StopAll(true);
throw;
}
Ignition::StopAll(true);
}
BOOST_AUTO_TEST_CASE(GetEnumValueInvalid)
{
BinaryFields some(43956293, 567894632, 253945, 107576622);
InteropUnpooledMemory mem(1024);
FillMem(mem, some);
TemplatedBinaryIdResolver<BinaryOuter> resolver;
BinaryObjectImpl binObj(mem, 0, &resolver, 0);
BOOST_CHECK_THROW(binObj.GetEnumValue(), IgniteError);
}
void CheckBinaryEnumEntry(int32_t typeId, int32_t ordinal)
{
InteropUnpooledMemory mem(1024);
InteropOutputStream outStream(&mem);
BinaryWriterImpl writer(&outStream, 0);
BinaryEnumEntry original(typeId, ordinal);
writer.WriteBinaryEnum(original);
outStream.Synchronize();
InteropInputStream inStream(&mem);
BinaryReaderImpl reader(&inStream);
BinaryEnumEntry result = reader.ReadBinaryEnum();
if (original.IsNull())
{
BOOST_CHECK(result.IsNull());
return;
}
BOOST_CHECK_EQUAL(original.GetTypeId(), result.GetTypeId());
BOOST_CHECK_EQUAL(original.GetOrdinal(), result.GetOrdinal());
}
BOOST_AUTO_TEST_CASE(ReadWriteBinaryEnum)
{
CheckBinaryEnumEntry(1234567, 42);
CheckBinaryEnumEntry(1234567, 1);
CheckBinaryEnumEntry(1, 1);
CheckBinaryEnumEntry(6754, 0);
CheckBinaryEnumEntry(0, 0);
CheckBinaryEnumEntry(0, 1);
}
template<typename T>
void CheckUserEnum(T val)
{
InteropUnpooledMemory mem(1024);
InteropOutputStream outStream(&mem);
BinaryWriterImpl writer(&outStream, 0);
writer.WriteEnum(val);
outStream.Synchronize();
InteropInputStream inStream(&mem);
BinaryReaderImpl reader(&inStream);
T result = reader.ReadEnum<T>();
BOOST_CHECK_EQUAL(val, result);
}
BOOST_AUTO_TEST_CASE(ReadWriteUserEnum)
{
CheckUserEnum(TestEnum::TEST_ZERO);
CheckUserEnum(TestEnum::TEST_NON_ZERO);
CheckUserEnum(TestEnum::TEST_NEGATIVE_42);
CheckUserEnum(TestEnum::TEST_SOME_BIG);
}
template<typename T>
void CheckUserEnumPtr(T val)
{
InteropUnpooledMemory mem(1024);
InteropOutputStream outStream(&mem);
BinaryWriterImpl writer(&outStream, 0);
writer.WriteEnum(&val);
outStream.Synchronize();
InteropInputStream inStream(&mem);
BinaryReaderImpl reader(&inStream);
T* result = reader.ReadEnum<T*>();
BOOST_CHECK_EQUAL(val, *result);
delete result;
}
BOOST_AUTO_TEST_CASE(ReadWriteUserEnumPtr)
{
CheckUserEnumPtr(TestEnum::TEST_ZERO);
CheckUserEnumPtr(TestEnum::TEST_NON_ZERO);
CheckUserEnumPtr(TestEnum::TEST_NEGATIVE_42);
CheckUserEnumPtr(TestEnum::TEST_SOME_BIG);
}
BOOST_AUTO_TEST_CASE(ReadWriteUserEnumNullPtr)
{
InteropUnpooledMemory mem(1024);
InteropOutputStream outStream(&mem);
BinaryWriterImpl writer(&outStream, 0);
writer.WriteEnum<TestEnum::Type*>(0);
outStream.Synchronize();
InteropInputStream inStream(&mem);
BinaryReaderImpl reader(&inStream);
TestEnum::Type* result = reader.ReadEnum<TestEnum::Type*>();
BOOST_CHECK(result == 0);
delete result;
}
BOOST_AUTO_TEST_SUITE_END()