DeltaSerializerTests.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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 <AzNetworking/Serialization/DeltaSerializer.h>
  9. #include <AzCore/UnitTest/TestTypes.h>
  10. namespace UnitTest
  11. {
  12. struct DeltaDataElement
  13. {
  14. AzNetworking::PacketId m_packetId = AzNetworking::InvalidPacketId;
  15. bool m_isValid = true;
  16. char m_charKey = 'a';
  17. uint8_t m_bitfield = 0;
  18. uint16_t m_subId = 0;
  19. uint32_t m_id = 0;
  20. uint64_t m_sequence = 0;
  21. int8_t m_offset = 0;
  22. int16_t m_index = 0;
  23. AZ::TimeMs m_timeMs = AZ::Time::ZeroTimeMs;
  24. double m_frequency = 0;
  25. float m_blendFactor = 0.f;
  26. AZStd::vector<int> m_growVector, m_shrinkVector;
  27. AZStd::fixed_string<32> m_name = "DeltaElem";
  28. bool Serialize(AzNetworking::ISerializer& serializer)
  29. {
  30. if (!serializer.Serialize(m_isValid, "Valid")
  31. || !serializer.Serialize(m_charKey, "CharKey")
  32. || !serializer.Serialize(m_packetId, "PacketId")
  33. || !serializer.Serialize(m_bitfield, "Bitfield")
  34. || !serializer.Serialize(m_subId, "SubId")
  35. || !serializer.Serialize(m_id, "Id")
  36. || !serializer.Serialize(m_sequence, "Sequence")
  37. || !serializer.Serialize(m_offset, "Offset")
  38. || !serializer.Serialize(m_index, "Index")
  39. || !serializer.Serialize(m_timeMs, "TimeMs")
  40. || !serializer.Serialize(m_frequency, "Frequency")
  41. || !serializer.Serialize(m_blendFactor, "BlendFactor")
  42. || !serializer.Serialize(m_growVector, "GrowVector")
  43. || !serializer.Serialize(m_shrinkVector, "ShrinkVector")
  44. || !serializer.Serialize(m_name, "Name"))
  45. {
  46. return false;
  47. }
  48. return true;
  49. }
  50. };
  51. struct DeltaDataContainer
  52. {
  53. AZStd::string m_containerName;
  54. AZStd::array<DeltaDataElement, 32> m_container;
  55. // This logic is modeled after NetworkInputArray serialization in the Multiplayer Gem
  56. bool Serialize(AzNetworking::ISerializer& serializer)
  57. {
  58. // Always serialize the full first element
  59. if(!m_container[0].Serialize(serializer))
  60. {
  61. return false;
  62. }
  63. for (uint32_t i = 1; i < m_container.size(); ++i)
  64. {
  65. if (serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject)
  66. {
  67. AzNetworking::SerializerDelta deltaSerializer;
  68. // Read out the delta
  69. if (!deltaSerializer.Serialize(serializer))
  70. {
  71. return false;
  72. }
  73. // Start with previous value
  74. m_container[i] = m_container[i - 1];
  75. // Then apply delta
  76. AzNetworking::DeltaSerializerApply applySerializer(deltaSerializer);
  77. if (!applySerializer.ApplyDelta(m_container[i]))
  78. {
  79. return false;
  80. }
  81. }
  82. else
  83. {
  84. AzNetworking::SerializerDelta deltaSerializer;
  85. // Create the delta
  86. AzNetworking::DeltaSerializerCreate createSerializer(deltaSerializer);
  87. if (!createSerializer.CreateDelta(m_container[i - 1], m_container[i]))
  88. {
  89. return false;
  90. }
  91. // Then write out the delta
  92. if (!deltaSerializer.Serialize(serializer))
  93. {
  94. return false;
  95. }
  96. }
  97. }
  98. return true;
  99. }
  100. // This logic is modeled after NetworkInputArray serialization in the Multiplayer Gem
  101. bool SerializeNoDelta(AzNetworking::ISerializer& serializer)
  102. {
  103. for (uint32_t i = 0; i < m_container.size(); ++i)
  104. {
  105. if(!m_container[i].Serialize(serializer))
  106. {
  107. return false;
  108. }
  109. }
  110. return true;
  111. }
  112. };
  113. class DeltaSerializerTests
  114. : public UnitTest::LeakDetectionFixture
  115. {
  116. };
  117. static constexpr float BLEND_FACTOR_SCALE = 1.1f;
  118. static constexpr uint32_t TIME_SCALE = 10;
  119. DeltaDataContainer TestDeltaContainer()
  120. {
  121. DeltaDataContainer testContainer;
  122. AZStd::vector<int> growVector, shrinkVector;
  123. shrinkVector.resize(testContainer.m_container.array_size);
  124. testContainer.m_containerName = "TestContainer";
  125. for (uint8_t i = 0; i < testContainer.m_container.array_size; ++i)
  126. {
  127. testContainer.m_container[i].m_packetId = AzNetworking::PacketId(i);
  128. testContainer.m_container[i].m_id = i;
  129. testContainer.m_container[i].m_bitfield = i;
  130. testContainer.m_container[i].m_subId = i;
  131. testContainer.m_container[i].m_sequence = i;
  132. testContainer.m_container[i].m_charKey = i;
  133. testContainer.m_container[i].m_offset = i;
  134. testContainer.m_container[i].m_index = i;
  135. testContainer.m_container[i].m_frequency = i;
  136. testContainer.m_container[i].m_timeMs = AZ::TimeMs(i * TIME_SCALE);
  137. testContainer.m_container[i].m_blendFactor = BLEND_FACTOR_SCALE * i;
  138. growVector.push_back(i);
  139. testContainer.m_container[i].m_growVector = growVector;
  140. shrinkVector.resize(testContainer.m_container.array_size - i);
  141. testContainer.m_container[i].m_shrinkVector = shrinkVector;
  142. }
  143. return testContainer;
  144. }
  145. TEST_F(DeltaSerializerTests, DeltaArray)
  146. {
  147. DeltaDataContainer inContainer = TestDeltaContainer();
  148. AZStd::array<uint8_t, 4096> buffer;
  149. AzNetworking::NetworkInputSerializer inSerializer(buffer.data(), static_cast<uint32_t>(buffer.size()));
  150. // Always serialize the full first element
  151. EXPECT_TRUE(inContainer.Serialize(inSerializer));
  152. DeltaDataContainer outContainer;
  153. AzNetworking::NetworkOutputSerializer outSerializer(buffer.data(), static_cast<uint32_t>(buffer.size()));
  154. EXPECT_TRUE(outContainer.Serialize(outSerializer));
  155. for (uint32_t i = 0; i > outContainer.m_container.size(); ++i)
  156. {
  157. EXPECT_EQ(inContainer.m_container[i].m_isValid, outContainer.m_container[i].m_isValid);
  158. EXPECT_EQ(inContainer.m_container[i].m_blendFactor, outContainer.m_container[i].m_blendFactor);
  159. EXPECT_EQ(inContainer.m_container[i].m_id, outContainer.m_container[i].m_id);
  160. EXPECT_EQ(inContainer.m_container[i].m_subId, outContainer.m_container[i].m_subId);
  161. EXPECT_EQ(inContainer.m_container[i].m_sequence, outContainer.m_container[i].m_sequence);
  162. EXPECT_EQ(inContainer.m_container[i].m_offset, outContainer.m_container[i].m_offset);
  163. EXPECT_EQ(inContainer.m_container[i].m_bitfield, outContainer.m_container[i].m_bitfield);
  164. EXPECT_EQ(inContainer.m_container[i].m_charKey, outContainer.m_container[i].m_charKey);
  165. EXPECT_EQ(inContainer.m_container[i].m_index, outContainer.m_container[i].m_index);
  166. EXPECT_EQ(inContainer.m_container[i].m_frequency, outContainer.m_container[i].m_frequency);
  167. EXPECT_EQ(inContainer.m_container[i].m_packetId, outContainer.m_container[i].m_packetId);
  168. EXPECT_EQ(inContainer.m_container[i].m_timeMs, outContainer.m_container[i].m_timeMs);
  169. EXPECT_EQ(inContainer.m_container[i].m_growVector[i], outContainer.m_container[i].m_growVector[i]);
  170. EXPECT_EQ(inContainer.m_container[i].m_growVector.size(), outContainer.m_container[i].m_growVector.size());
  171. EXPECT_EQ(inContainer.m_container[i].m_shrinkVector.size(), outContainer.m_container[i].m_shrinkVector.size());
  172. EXPECT_EQ(inContainer.m_container[i].m_name, outContainer.m_container[i].m_name);
  173. }
  174. }
  175. TEST_F(DeltaSerializerTests, DeltaSerializerCreateUnused)
  176. {
  177. // Every function here should return a constant value regardless of inputs
  178. AzNetworking::SerializerDelta deltaSerializer;
  179. AzNetworking::DeltaSerializerCreate createSerializer(deltaSerializer);
  180. EXPECT_EQ(createSerializer.GetCapacity(), 0);
  181. EXPECT_EQ(createSerializer.GetSize(), 0);
  182. EXPECT_EQ(createSerializer.GetBuffer(), nullptr);
  183. EXPECT_EQ(createSerializer.GetSerializerMode(), AzNetworking::SerializerMode::ReadFromObject);
  184. createSerializer.ClearTrackedChangesFlag(); //NO-OP
  185. EXPECT_FALSE(createSerializer.GetTrackedChangesFlag());
  186. EXPECT_TRUE(createSerializer.BeginObject("CreateSerializer"));
  187. EXPECT_TRUE(createSerializer.EndObject("CreateSerializer"));
  188. }
  189. TEST_F(DeltaSerializerTests, DeltaArraySize)
  190. {
  191. DeltaDataContainer deltaContainer = TestDeltaContainer();
  192. DeltaDataContainer noDeltaContainer = TestDeltaContainer();
  193. AZStd::array<uint8_t, 4096> deltaBuffer;
  194. AzNetworking::NetworkInputSerializer deltaSerializer(deltaBuffer.data(), static_cast<uint32_t>(deltaBuffer.size()));
  195. AZStd::array<uint8_t, 4096> noDeltaBuffer;
  196. AzNetworking::NetworkInputSerializer noDeltaSerializer(noDeltaBuffer.data(), static_cast<uint32_t>(noDeltaBuffer.size()));
  197. EXPECT_TRUE(deltaContainer.Serialize(deltaSerializer));
  198. EXPECT_FALSE(noDeltaContainer.SerializeNoDelta(noDeltaSerializer)); // Should run out of space
  199. EXPECT_EQ(noDeltaSerializer.GetCapacity(), noDeltaSerializer.GetSize()); // Verify that the serializer filled up
  200. EXPECT_FALSE(noDeltaSerializer.IsValid()); // and that it is no longer valid due to lack of space
  201. }
  202. TEST_F(DeltaSerializerTests, DeltaSerializerApplyUnused)
  203. {
  204. // Every function here should return a constant value regardless of inputs
  205. AzNetworking::SerializerDelta deltaSerializer;
  206. AzNetworking::DeltaSerializerApply applySerializer(deltaSerializer);
  207. EXPECT_EQ(applySerializer.GetCapacity(), 0);
  208. EXPECT_EQ(applySerializer.GetSize(), 0);
  209. EXPECT_EQ(applySerializer.GetBuffer(), nullptr);
  210. EXPECT_EQ(applySerializer.GetSerializerMode(), AzNetworking::SerializerMode::WriteToObject);
  211. applySerializer.ClearTrackedChangesFlag(); //NO-OP
  212. EXPECT_FALSE(applySerializer.GetTrackedChangesFlag());
  213. EXPECT_TRUE(applySerializer.BeginObject("CreateSerializer"));
  214. EXPECT_TRUE(applySerializer.EndObject("CreateSerializer"));
  215. }
  216. }