| /* |
| * 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 <gtest/gtest.h> |
| |
| #include "ByteArrayFixture.hpp" |
| #include "DataInputInternal.hpp" |
| #include "DataOutputInternal.hpp" |
| #include "PdxType.hpp" |
| #include "PdxTypeRegistry.hpp" |
| #include "PdxTypes.hpp" |
| |
| namespace { |
| using apache::geode::client::ByteArray; |
| using apache::geode::client::DataInputInternal; |
| using apache::geode::client::DataOutputInternal; |
| using apache::geode::client::PdxFieldTypes; |
| using apache::geode::client::PdxType; |
| using apache::geode::client::PdxTypeRegistry; |
| using apache::geode::client::PdxTypes; |
| |
| const std::string gemfireJsonClassName = "__GEMFIRE_JSON"; |
| |
| class PdxTypeTest : public ::testing::Test, public ByteArrayFixture {}; |
| |
| TEST_F(PdxTypeTest, testTwoObjectsWithSameClassnameAndSameFieldsAreEquals) { |
| PdxTypeRegistry pdxTypeRegistry(nullptr); |
| |
| PdxType m_pdxType1(pdxTypeRegistry, gemfireJsonClassName, false); |
| PdxType m_pdxType2(pdxTypeRegistry, gemfireJsonClassName, false); |
| |
| m_pdxType1.addVariableLengthTypeField("bar0", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType1.addVariableLengthTypeField("bar1", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType2.addVariableLengthTypeField("bar0", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType2.addVariableLengthTypeField("bar1", "string", |
| PdxFieldTypes::STRING); |
| |
| EXPECT_TRUE(m_pdxType1 == m_pdxType2); |
| } |
| |
| TEST_F(PdxTypeTest, |
| testTwoObjectsWithSameClassnameAndSameFieldsInDifferentOrderAreEquals) { |
| PdxTypeRegistry pdxTypeRegistry(nullptr); |
| |
| PdxType m_pdxType1(pdxTypeRegistry, gemfireJsonClassName, false); |
| PdxType m_pdxType2(pdxTypeRegistry, gemfireJsonClassName, false); |
| m_pdxType1.addVariableLengthTypeField("bar1", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType1.addVariableLengthTypeField("bar0", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType2.addVariableLengthTypeField("bar0", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType2.addVariableLengthTypeField("bar1", "string", |
| PdxFieldTypes::STRING); |
| |
| EXPECT_TRUE(m_pdxType1 == m_pdxType2); |
| } |
| |
| TEST_F(PdxTypeTest, |
| testTwoObjectsWithDifferentClassnameButSameFieldsAreNotEquals) { |
| PdxTypeRegistry pdxTypeRegistry(nullptr); |
| |
| PdxType m_pdxType1(pdxTypeRegistry, gemfireJsonClassName, false); |
| PdxType m_pdxType2(pdxTypeRegistry, "otherClassName", false); |
| |
| m_pdxType1.addVariableLengthTypeField("bar0", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType1.addVariableLengthTypeField("bar1", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType2.addVariableLengthTypeField("bar0", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType2.addVariableLengthTypeField("bar1", "string", |
| PdxFieldTypes::STRING); |
| |
| EXPECT_FALSE(m_pdxType1 == m_pdxType2); |
| } |
| |
| TEST_F(PdxTypeTest, testTwoObjectsWithSameFieldsHaveTheSameHash) { |
| PdxTypeRegistry pdxTypeRegistry(nullptr); |
| |
| PdxType m_pdxType1(pdxTypeRegistry, gemfireJsonClassName, false); |
| PdxType m_pdxType2(pdxTypeRegistry, gemfireJsonClassName, false); |
| |
| m_pdxType1.addVariableLengthTypeField("bar0", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType1.addVariableLengthTypeField("bar1", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType1.addVariableLengthTypeField("bar2", "string", |
| PdxFieldTypes::STRING); |
| |
| m_pdxType2.addVariableLengthTypeField("bar0", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType2.addVariableLengthTypeField("bar1", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType2.addVariableLengthTypeField("bar2", "string", |
| PdxFieldTypes::STRING); |
| |
| std::hash<PdxType> type1Hash; |
| std::hash<PdxType> type2Hash; |
| |
| EXPECT_EQ(type1Hash(m_pdxType1), type2Hash(m_pdxType2)); |
| } |
| |
| TEST_F(PdxTypeTest, testTwoObjectsWithDifferentFieldsHaveDifferentHash) { |
| PdxTypeRegistry pdxTypeRegistry(nullptr); |
| |
| PdxType m_pdxType1(pdxTypeRegistry, gemfireJsonClassName, false); |
| PdxType m_pdxType2(pdxTypeRegistry, gemfireJsonClassName, false); |
| |
| m_pdxType1.addVariableLengthTypeField("bar0", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType1.addVariableLengthTypeField("bar1", "string", |
| PdxFieldTypes::STRING); |
| |
| m_pdxType2.addVariableLengthTypeField("bar2", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType2.addVariableLengthTypeField("bar3", "string", |
| PdxFieldTypes::STRING); |
| |
| std::hash<PdxType> type1Hash; |
| std::hash<PdxType> type2Hash; |
| |
| EXPECT_NE(type1Hash(m_pdxType1), type2Hash(m_pdxType2)); |
| } |
| |
| TEST_F(PdxTypeTest, |
| testTwoObjectsWithSameFieldsInDifferentOrderHaveTheSameHash) { |
| PdxTypeRegistry pdxTypeRegistry(nullptr); |
| |
| PdxType m_pdxType1(pdxTypeRegistry, gemfireJsonClassName, false); |
| PdxType m_pdxType2(pdxTypeRegistry, gemfireJsonClassName, false); |
| |
| m_pdxType1.addVariableLengthTypeField("bar0", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType1.addVariableLengthTypeField("bar1", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType1.addVariableLengthTypeField("bar2", "string", |
| PdxFieldTypes::STRING); |
| |
| m_pdxType2.addVariableLengthTypeField("bar1", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType2.addVariableLengthTypeField("bar2", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType2.addVariableLengthTypeField("bar0", "string", |
| PdxFieldTypes::STRING); |
| |
| std::hash<PdxType> type1Hash; |
| std::hash<PdxType> type2Hash; |
| |
| EXPECT_EQ(type1Hash(m_pdxType1), type2Hash(m_pdxType2)); |
| } |
| |
| TEST_F(PdxTypeTest, |
| testTwoObjectsWithSameFieldsNamesButDifferentTypesHaveDifferentHash) { |
| PdxTypeRegistry pdxTypeRegistry(nullptr); |
| |
| PdxType m_pdxType1(pdxTypeRegistry, gemfireJsonClassName, false); |
| PdxType m_pdxType2(pdxTypeRegistry, gemfireJsonClassName, false); |
| |
| m_pdxType1.addVariableLengthTypeField("bar0", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType1.addVariableLengthTypeField("bar1", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType1.addVariableLengthTypeField("bar2", "string", |
| PdxFieldTypes::STRING); |
| |
| m_pdxType2.addVariableLengthTypeField("bar0", "string", |
| PdxFieldTypes::STRING); |
| m_pdxType2.addFixedLengthTypeField("bar1", "bool", PdxFieldTypes::BOOLEAN, |
| PdxTypes::kPdxBooleanSize); |
| m_pdxType2.addFixedLengthTypeField("bar2", "int", PdxFieldTypes::INT, |
| PdxTypes::kPdxIntegerSize); |
| |
| std::hash<PdxType> type1Hash; |
| std::hash<PdxType> type2Hash; |
| |
| EXPECT_NE(type1Hash(m_pdxType1), type2Hash(m_pdxType2)); |
| } |
| |
| TEST_F(PdxTypeTest, testSerializeJavaPdxType) { |
| PdxTypeRegistry pdx_type_registry{nullptr}; |
| PdxType pdx_type{pdx_type_registry, gemfireJsonClassName, false}; |
| |
| pdx_type.addVariableLengthTypeField("foo", "", PdxFieldTypes::STRING); |
| pdx_type.addVariableLengthTypeField("alice", "", PdxFieldTypes::STRING); |
| pdx_type.addFixedLengthTypeField("bar1", "", PdxFieldTypes::BOOLEAN, |
| PdxTypes::kPdxBooleanSize); |
| |
| DataOutputInternal out; |
| pdx_type.toData(out); |
| |
| EXPECT_BYTEARRAY_EQ( |
| "2D2B5700256F72672E6170616368652E67656F64652E7064782E696E7465726E" |
| "616C2E5064785479706557000E5F5F47454D464952455F4A534F4E0000000000" |
| "0000000103570003666F6F000000000000000009000000000000000000570005" |
| "616C696365000000010000000109000000000000000000570004626172310000" |
| "00020000000000000000000000000000", |
| ByteArray(out.getBuffer(), out.getBufferLength())); |
| } |
| |
| TEST_F(PdxTypeTest, testSerializeNoJavaPdxType) { |
| PdxTypeRegistry pdx_type_registry{nullptr}; |
| PdxType pdx_type{pdx_type_registry, gemfireJsonClassName, false, false}; |
| |
| pdx_type.addVariableLengthTypeField("foo", "", PdxFieldTypes::STRING); |
| pdx_type.addVariableLengthTypeField("alice", "", PdxFieldTypes::STRING); |
| pdx_type.addFixedLengthTypeField("bar1", "", PdxFieldTypes::BOOLEAN, |
| PdxTypes::kPdxBooleanSize); |
| |
| DataOutputInternal out; |
| pdx_type.toData(out); |
| |
| EXPECT_BYTEARRAY_EQ( |
| "2D2B5700256F72672E6170616368652E67656F64652E7064782E696E7465726E" |
| "616C2E5064785479706557000E5F5F47454D464952455F4A534F4E0100000000" |
| "0000000103570003666F6F000000000000000009000000000000000000570005" |
| "616C696365000000010000000109000000000000000000570004626172310000" |
| "00020000000000000000000000000000", |
| ByteArray(out.getBuffer(), out.getBufferLength())); |
| } |
| |
| TEST_F(PdxTypeTest, testDeserializeJavaPdxType) { |
| PdxTypeRegistry pdx_type_registry{nullptr}; |
| PdxType pdx_expected{pdx_type_registry, gemfireJsonClassName, false}; |
| |
| pdx_expected.addVariableLengthTypeField("foo", "", PdxFieldTypes::STRING); |
| pdx_expected.addVariableLengthTypeField("alice", "", PdxFieldTypes::STRING); |
| pdx_expected.addFixedLengthTypeField("bar1", "", PdxFieldTypes::BOOLEAN, |
| PdxTypes::kPdxBooleanSize); |
| |
| DataOutputInternal out; |
| pdx_expected.toData(out); |
| |
| auto pdx_type = std::dynamic_pointer_cast<PdxType>( |
| PdxType::CreateDeserializable(pdx_type_registry)); |
| DataInputInternal in(out.getBuffer(), out.getBufferLength()); |
| pdx_type->fromData(in); |
| |
| EXPECT_EQ(pdx_expected, *pdx_type); |
| } |
| |
| TEST_F(PdxTypeTest, testDeserializeNoJavaPdxType) { |
| PdxTypeRegistry pdx_type_registry{nullptr}; |
| PdxType pdx_expected{pdx_type_registry, gemfireJsonClassName, false, false}; |
| |
| pdx_expected.addVariableLengthTypeField("foo", "", PdxFieldTypes::STRING); |
| pdx_expected.addVariableLengthTypeField("alice", "", PdxFieldTypes::STRING); |
| pdx_expected.addFixedLengthTypeField("bar1", "", PdxFieldTypes::BOOLEAN, |
| PdxTypes::kPdxBooleanSize); |
| |
| DataOutputInternal out; |
| pdx_expected.toData(out); |
| |
| auto pdx_type = std::dynamic_pointer_cast<PdxType>( |
| PdxType::CreateDeserializable(pdx_type_registry)); |
| DataInputInternal in(out.getBuffer(), out.getBufferLength()); |
| pdx_type->fromData(in); |
| |
| EXPECT_EQ(pdx_expected, *pdx_type); |
| } |
| |
| } // namespace |