NetworkInputOutputSerializerTests.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Console/Console.h>
  9. #include <AzNetworking/Serialization/NetworkInputSerializer.h>
  10. #include <AzNetworking/Serialization/NetworkOutputSerializer.h>
  11. #include <AzCore/std/string/memorytoascii.h>
  12. #include <AzCore/StringFunc/StringFunc.h>
  13. #include <AzCore/UnitTest/TestTypes.h>
  14. #include <AzNetworking/Utilities/NetworkIncludes.h>
  15. namespace UnitTest
  16. {
  17. struct InputOutputDataElement
  18. {
  19. bool testBool = false;
  20. char testChar = 'a';
  21. int8_t testInt8 = 0;
  22. int16_t testInt16 = 1;
  23. int32_t testInt32 = 2;
  24. int64_t testInt64 = 3;
  25. uint8_t testUint8 = 0;
  26. uint16_t testUint16 = 1;
  27. uint32_t testUint32 = 2;
  28. uint64_t testUint64 = 3;
  29. double testDouble = 1.0;
  30. float testFloat = 1.f;
  31. AZStd::fixed_string<32> testFixedString = "FixedString";
  32. bool Serialize(AzNetworking::ISerializer& serializer)
  33. {
  34. if (!serializer.Serialize(testBool, "TestBool") || !serializer.Serialize(testChar, "TestChar") ||
  35. !serializer.Serialize(testInt8, "TestInt8") || !serializer.Serialize(testInt16, "TestInt16") ||
  36. !serializer.Serialize(testInt32, "TestInt32") || !serializer.Serialize(testInt64, "TestInt64") ||
  37. !serializer.Serialize(testUint8, "TestUint8") || !serializer.Serialize(testUint16, "TestUint16") ||
  38. !serializer.Serialize(testUint32, "TestUint32") || !serializer.Serialize(testUint64, "TestUint64") ||
  39. !serializer.Serialize(testDouble, "TestDouble") || !serializer.Serialize(testFloat, "TestFloat") ||
  40. !serializer.Serialize(testFixedString, "TestFixedString"))
  41. {
  42. return false;
  43. }
  44. return true;
  45. }
  46. };
  47. class InputOutputSerializerTests : public LeakDetectionFixture
  48. {
  49. };
  50. TEST_F(InputOutputSerializerTests, TestTypeValidatingSerializer)
  51. {
  52. const size_t Capacity = 2048;
  53. const uint8_t ExpectedSerializedBytes = 57;
  54. const uint8_t CopyBufferSize = 4;
  55. AZStd::array<uint8_t, Capacity> buffer;
  56. AZStd::array<uint8_t, CopyBufferSize> copyBuffer;
  57. copyBuffer.fill(1);
  58. InputOutputDataElement inElement;
  59. AzNetworking::NetworkInputSerializer inSerializer(
  60. buffer.data(), static_cast<uint32_t>(buffer.size()));
  61. EXPECT_NE(inSerializer.GetBuffer(), nullptr);
  62. EXPECT_EQ(inSerializer.GetCapacity(), Capacity);
  63. EXPECT_TRUE(inElement.Serialize(inSerializer));
  64. EXPECT_EQ(inSerializer.GetSize(), ExpectedSerializedBytes);
  65. EXPECT_TRUE(inSerializer.CopyToBuffer(copyBuffer.data(), static_cast<uint32_t>(copyBuffer.size())));
  66. EXPECT_EQ(inSerializer.GetSize(), ExpectedSerializedBytes + CopyBufferSize);
  67. inSerializer.ClearTrackedChangesFlag();
  68. EXPECT_FALSE(inSerializer.GetTrackedChangesFlag());
  69. InputOutputDataElement outElement;
  70. AzNetworking::NetworkOutputSerializer outSerializer(
  71. buffer.data(), static_cast<uint32_t>(buffer.size()));
  72. EXPECT_NE(outSerializer.GetBuffer(), nullptr);
  73. EXPECT_EQ(outSerializer.GetCapacity(), Capacity);
  74. EXPECT_TRUE(outElement.Serialize(outSerializer));
  75. EXPECT_EQ(outSerializer.GetSize(), ExpectedSerializedBytes);
  76. outSerializer.ClearTrackedChangesFlag();
  77. EXPECT_FALSE(outSerializer.GetTrackedChangesFlag());
  78. EXPECT_EQ(inElement.testBool, outElement.testBool);
  79. EXPECT_EQ(inElement.testChar, outElement.testChar);
  80. EXPECT_EQ(inElement.testInt8, outElement.testInt8);
  81. EXPECT_EQ(inElement.testInt16, outElement.testInt16);
  82. EXPECT_EQ(inElement.testInt32, outElement.testInt32);
  83. EXPECT_EQ(inElement.testUint8, outElement.testUint8);
  84. EXPECT_EQ(inElement.testUint16, outElement.testUint16);
  85. EXPECT_EQ(inElement.testUint32, outElement.testUint32);
  86. EXPECT_EQ(inElement.testUint64, outElement.testUint64);
  87. EXPECT_EQ(inElement.testDouble, outElement.testDouble);
  88. EXPECT_EQ(inElement.testFloat, outElement.testFloat);
  89. EXPECT_EQ(inElement.testFixedString, outElement.testFixedString);
  90. }
  91. /**
  92. * Internal helper function to test network serialization for a specific type against a known expected value
  93. *
  94. * \param[in] value The value to serialize
  95. * \param[in] label The label to identify the type under test in case of a failed expectation
  96. * \param[in] expectedData The expected buffer to compare the results to
  97. * \param[in] expectedSize The expected buffer size to compare the results to
  98. */
  99. template<typename T>
  100. void InternalTestSerializeType(T value, const char* label, AZStd::span<uint8_t> expectedData)
  101. {
  102. constexpr size_t Capacity = 32;
  103. AZStd::array<uint8_t, Capacity> buffer;
  104. buffer.fill(0);
  105. AzNetworking::NetworkInputSerializer inSerializer(buffer.data(), static_cast<uint32_t>(buffer.size()));
  106. AzNetworking::ISerializer& serializer = inSerializer;
  107. EXPECT_TRUE(serializer.Serialize(value, label)) << "Serialize failed for " << label;
  108. EXPECT_EQ(serializer.GetSize(), expectedData.size()) << "Resulting buffer size for " << label << "does not match expected (" << serializer.GetSize() << " != " << expectedData.size() << ")";
  109. auto resultHexStr = AZStd::MemoryToASCII::ToString(serializer.GetBuffer(), serializer.GetSize(), serializer.GetSize(), 512, AZStd::MemoryToASCII::Options::Binary);
  110. AZ::StringFunc::TrimWhiteSpace(resultHexStr, true, true);
  111. auto expectedHexStr = AZStd::MemoryToASCII::ToString(expectedData.data(), expectedData.size(), expectedData.size(), 512, AZStd::MemoryToASCII::Options::Binary);
  112. AZ::StringFunc::TrimWhiteSpace(expectedHexStr, true, true);
  113. EXPECT_TRUE(memcmp(serializer.GetBuffer(), expectedData.data(), serializer.GetSize())==0) << "Resulting bytes for " << label << " do not match expected (" << resultHexStr.c_str() << " != " << expectedHexStr.c_str() << ")";
  114. }
  115. TEST_F(InputOutputSerializerTests, TestFixedSerialization)
  116. {
  117. {
  118. bool testValue = true;
  119. auto expected = AZStd::to_array<uint8_t>({ 0x01 });
  120. InternalTestSerializeType(testValue, "bool(true)", expected);
  121. }
  122. {
  123. bool testValue = false;
  124. auto expected = AZStd::to_array<uint8_t>({ 0x00 });
  125. InternalTestSerializeType(testValue, "boolfalse)", expected);
  126. }
  127. {
  128. int8_t testValue = 0x12;
  129. auto expected = AZStd::to_array<uint8_t>({ 0x92 });
  130. InternalTestSerializeType(testValue, "int8", expected);
  131. }
  132. {
  133. int16_t testValue = 0x1234;
  134. auto expected = AZStd::to_array<uint8_t>({ 0x92, 0x34 });
  135. InternalTestSerializeType(testValue, "int16", expected);
  136. }
  137. {
  138. int32_t testValue = 0x12345678;
  139. auto expected = AZStd::to_array<uint8_t>({ 0x92, 0x34, 0x56, 0x78 });
  140. InternalTestSerializeType(testValue, "int32", expected);
  141. }
  142. {
  143. int64_t testValue = 0x123456789abcdef;
  144. auto expected = AZStd::to_array<uint8_t>({ 0x81, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef });
  145. InternalTestSerializeType(testValue, "int64", expected);
  146. }
  147. {
  148. uint8_t testValue = 0x12;
  149. auto expected = AZStd::to_array<uint8_t>({ 0x12 });
  150. InternalTestSerializeType(testValue, "uint8", expected);
  151. }
  152. {
  153. uint16_t testValue = 0x1234;
  154. auto expected = AZStd::to_array<uint8_t>({ 0x12, 0x34 });
  155. InternalTestSerializeType(testValue, "uint16", expected);
  156. }
  157. {
  158. uint32_t testValue = 0x12345678;
  159. auto expected = AZStd::to_array<uint8_t>({ 0x12, 0x34, 0x56, 0x78 });
  160. InternalTestSerializeType(testValue, "uint32", expected);
  161. }
  162. {
  163. uint64_t testValue = 0x123456789abcdef;
  164. auto expected = AZStd::to_array<uint8_t>({ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef });
  165. InternalTestSerializeType(testValue, "uint64", expected);
  166. }
  167. {
  168. double testValue = 1.0;
  169. auto expected = AZStd::to_array<uint8_t>({ 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
  170. InternalTestSerializeType(testValue, "double", expected);
  171. }
  172. {
  173. float testValue = 1.;
  174. auto expected = AZStd::to_array<uint8_t>({ 0x3f, 0x80, 0x00, 0x00 });
  175. InternalTestSerializeType(testValue, "float", expected);
  176. }
  177. {
  178. AZStd::fixed_string<32> testValue = "Fixed";
  179. auto expected = AZStd::to_array<uint8_t>({ 0x05, 0x05, 0x46, 0x69, 0x78, 0x65, 0x64 });
  180. InternalTestSerializeType(testValue, "string", expected);
  181. }
  182. }
  183. } // namespace UnitTest