DynamicMessageTest.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. #region Copyright notice and license
  2. // Protocol Buffers - Google's data interchange format
  3. // Copyright 2008 Google Inc. All rights reserved.
  4. // http://github.com/jskeet/dotnet-protobufs/
  5. // Original C++/Java/Python code:
  6. // http://code.google.com/p/protobuf/
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions are
  10. // met:
  11. //
  12. // * Redistributions of source code must retain the above copyright
  13. // notice, this list of conditions and the following disclaimer.
  14. // * Redistributions in binary form must reproduce the above
  15. // copyright notice, this list of conditions and the following disclaimer
  16. // in the documentation and/or other materials provided with the
  17. // distribution.
  18. // * Neither the name of Google Inc. nor the names of its
  19. // contributors may be used to endorse or promote products derived from
  20. // this software without specific prior written permission.
  21. //
  22. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  25. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  26. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  27. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  28. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  29. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  30. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  32. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. #endregion
  34. using System;
  35. using System.Collections.Generic;
  36. using Google.ProtocolBuffers.Descriptors;
  37. using Google.ProtocolBuffers.TestProtos;
  38. using NUnit.Framework;
  39. namespace Google.ProtocolBuffers
  40. {
  41. public class DynamicMessageTest
  42. {
  43. private ReflectionTester reflectionTester;
  44. private ReflectionTester extensionsReflectionTester;
  45. private ReflectionTester packedReflectionTester;
  46. public DynamicMessageTest()
  47. {
  48. reflectionTester = ReflectionTester.CreateTestAllTypesInstance();
  49. extensionsReflectionTester = ReflectionTester.CreateTestAllExtensionsInstance();
  50. packedReflectionTester = ReflectionTester.CreateTestPackedTypesInstance();
  51. }
  52. [Test]
  53. public void DynamicMessageAccessors()
  54. {
  55. IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
  56. reflectionTester.SetAllFieldsViaReflection(builder);
  57. IMessage message = builder.WeakBuild();
  58. reflectionTester.AssertAllFieldsSetViaReflection(message);
  59. }
  60. [Test]
  61. public void DoubleBuildError()
  62. {
  63. DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
  64. builder.Build();
  65. Assert.Throws<InvalidOperationException>(() => builder.Build());
  66. }
  67. [Test]
  68. public void DynamicMessageSettersRejectNull()
  69. {
  70. IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
  71. reflectionTester.AssertReflectionSettersRejectNull(builder);
  72. }
  73. [Test]
  74. public void DynamicMessageExtensionAccessors()
  75. {
  76. // We don't need to extensively test DynamicMessage's handling of
  77. // extensions because, frankly, it doesn't do anything special with them.
  78. // It treats them just like any other fields.
  79. IBuilder builder = DynamicMessage.CreateBuilder(TestAllExtensions.Descriptor);
  80. extensionsReflectionTester.SetAllFieldsViaReflection(builder);
  81. IMessage message = builder.WeakBuild();
  82. extensionsReflectionTester.AssertAllFieldsSetViaReflection(message);
  83. }
  84. [Test]
  85. public void DynamicMessageExtensionSettersRejectNull()
  86. {
  87. IBuilder builder = DynamicMessage.CreateBuilder(TestAllExtensions.Descriptor);
  88. extensionsReflectionTester.AssertReflectionSettersRejectNull(builder);
  89. }
  90. [Test]
  91. public void DynamicMessageRepeatedSetters()
  92. {
  93. IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
  94. reflectionTester.SetAllFieldsViaReflection(builder);
  95. reflectionTester.ModifyRepeatedFieldsViaReflection(builder);
  96. IMessage message = builder.WeakBuild();
  97. reflectionTester.AssertRepeatedFieldsModifiedViaReflection(message);
  98. }
  99. [Test]
  100. public void DynamicMessageRepeatedSettersRejectNull()
  101. {
  102. IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
  103. reflectionTester.AssertReflectionRepeatedSettersRejectNull(builder);
  104. }
  105. [Test]
  106. public void DynamicMessageDefaults()
  107. {
  108. reflectionTester.AssertClearViaReflection(DynamicMessage.GetDefaultInstance(TestAllTypes.Descriptor));
  109. reflectionTester.AssertClearViaReflection(DynamicMessage.CreateBuilder(TestAllTypes.Descriptor).Build());
  110. }
  111. [Test]
  112. public void DynamicMessageSerializedSize()
  113. {
  114. TestAllTypes message = TestUtil.GetAllSet();
  115. IBuilder dynamicBuilder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
  116. reflectionTester.SetAllFieldsViaReflection(dynamicBuilder);
  117. IMessage dynamicMessage = dynamicBuilder.WeakBuild();
  118. Assert.AreEqual(message.SerializedSize, dynamicMessage.SerializedSize);
  119. }
  120. [Test]
  121. public void DynamicMessageSerialization()
  122. {
  123. IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
  124. reflectionTester.SetAllFieldsViaReflection(builder);
  125. IMessage message = builder.WeakBuild();
  126. ByteString rawBytes = message.ToByteString();
  127. TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes);
  128. TestUtil.AssertAllFieldsSet(message2);
  129. // In fact, the serialized forms should be exactly the same, byte-for-byte.
  130. Assert.AreEqual(TestUtil.GetAllSet().ToByteString(), rawBytes);
  131. }
  132. [Test]
  133. public void DynamicMessageParsing()
  134. {
  135. TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
  136. TestUtil.SetAllFields(builder);
  137. TestAllTypes message = builder.Build();
  138. ByteString rawBytes = message.ToByteString();
  139. IMessage message2 = DynamicMessage.ParseFrom(TestAllTypes.Descriptor, rawBytes);
  140. reflectionTester.AssertAllFieldsSetViaReflection(message2);
  141. }
  142. [Test]
  143. public void DynamicMessagePackedSerialization()
  144. {
  145. IBuilder builder = DynamicMessage.CreateBuilder(TestPackedTypes.Descriptor);
  146. packedReflectionTester.SetPackedFieldsViaReflection(builder);
  147. IMessage message = builder.WeakBuild();
  148. ByteString rawBytes = message.ToByteString();
  149. TestPackedTypes message2 = TestPackedTypes.ParseFrom(rawBytes);
  150. TestUtil.AssertPackedFieldsSet(message2);
  151. // In fact, the serialized forms should be exactly the same, byte-for-byte.
  152. Assert.AreEqual(TestUtil.GetPackedSet().ToByteString(), rawBytes);
  153. }
  154. [Test]
  155. public void DynamicMessagePackedParsing()
  156. {
  157. TestPackedTypes.Builder builder = TestPackedTypes.CreateBuilder();
  158. TestUtil.SetPackedFields(builder);
  159. TestPackedTypes message = builder.Build();
  160. ByteString rawBytes = message.ToByteString();
  161. IMessage message2 = DynamicMessage.ParseFrom(TestPackedTypes.Descriptor, rawBytes);
  162. packedReflectionTester.AssertPackedFieldsSetViaReflection(message2);
  163. }
  164. [Test]
  165. public void DynamicMessageCopy()
  166. {
  167. TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
  168. TestUtil.SetAllFields(builder);
  169. TestAllTypes message = builder.Build();
  170. DynamicMessage copy = DynamicMessage.CreateBuilder(message).Build();
  171. reflectionTester.AssertAllFieldsSetViaReflection(copy);
  172. // Oneof
  173. FieldDescriptor bytesField =
  174. TestAllTypes.Descriptor.FindFieldByName("oneof_bytes");
  175. FieldDescriptor uint32Field =
  176. TestAllTypes.Descriptor.FindFieldByName("oneof_uint32");
  177. Assert.True(copy.HasField(bytesField));
  178. Assert.False(copy.HasField(uint32Field));
  179. DynamicMessage.Builder dynamicBuilder = DynamicMessage.CreateBuilder(message);
  180. dynamicBuilder[uint32Field] = 123U;
  181. DynamicMessage copy2 = dynamicBuilder.Build();
  182. Assert.IsFalse(copy2.HasField(bytesField));
  183. Assert.IsTrue(copy2.HasField(uint32Field));
  184. Assert.AreEqual(123U, copy2[uint32Field]);
  185. }
  186. [Test]
  187. public void ToBuilder()
  188. {
  189. DynamicMessage.Builder builder =
  190. DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
  191. reflectionTester.SetAllFieldsViaReflection(builder);
  192. int unknownFieldNum = 9;
  193. ulong unknownFieldVal = 90;
  194. builder.SetUnknownFields(UnknownFieldSet.CreateBuilder()
  195. .AddField(unknownFieldNum,
  196. UnknownField.CreateBuilder().AddVarint(unknownFieldVal).Build())
  197. .Build());
  198. DynamicMessage message = builder.Build();
  199. DynamicMessage derived = message.ToBuilder().Build();
  200. reflectionTester.AssertAllFieldsSetViaReflection(derived);
  201. IList<ulong> values = derived.UnknownFields.FieldDictionary[unknownFieldNum].VarintList;
  202. Assert.AreEqual(1, values.Count);
  203. Assert.AreEqual(unknownFieldVal, values[0]);
  204. }
  205. [Test]
  206. public void DynamicOneofMessage()
  207. {
  208. DynamicMessage.Builder builder =
  209. DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
  210. OneofDescriptor oneof = TestAllTypes.Descriptor.Oneofs[0];
  211. Assert.False(builder.HasOneof(oneof));
  212. Assert.AreSame(null, builder.OneofFieldDescriptor(oneof));
  213. reflectionTester.SetAllFieldsViaReflection(builder);
  214. Assert.True(builder.HasOneof(oneof));
  215. FieldDescriptor field = oneof.Field(3);
  216. Assert.AreSame(field, builder.OneofFieldDescriptor(oneof));
  217. Assert.AreEqual(TestUtil.ToBytes("604"), builder[field]);
  218. DynamicMessage message = builder.BuildPartial();
  219. Assert.IsTrue(message.HasOneof(oneof));
  220. DynamicMessage.Builder mergedBuilder =
  221. DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
  222. FieldDescriptor mergedField = oneof.Field(0);
  223. mergedBuilder[mergedField] = 123U;
  224. Assert.IsTrue(mergedBuilder.HasField(mergedField));
  225. mergedBuilder.MergeFrom(message);
  226. Assert.IsTrue(mergedBuilder.HasField(field));
  227. Assert.IsFalse(mergedBuilder.HasField(mergedField));
  228. mergedBuilder.ClearOneof(oneof);
  229. Assert.AreSame(null, mergedBuilder.OneofFieldDescriptor(oneof));
  230. message = mergedBuilder.Build();
  231. Assert.AreSame(null, message.OneofFieldDescriptor(oneof));
  232. }
  233. }
  234. }