blob: f9bfd84e7501378a09c10faee6a3cfa7ad995013 [file] [log] [blame]
csharptest71f662c2011-05-20 15:15:34 -05001#region Copyright notice and license
2
3// Protocol Buffers - Google's data interchange format
4// Copyright 2008 Google Inc. All rights reserved.
5// http://github.com/jskeet/dotnet-protobufs/
6// Original C++/Java/Python code:
7// http://code.google.com/p/protobuf/
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions are
11// met:
12//
13// * Redistributions of source code must retain the above copyright
14// notice, this list of conditions and the following disclaimer.
15// * Redistributions in binary form must reproduce the above
16// copyright notice, this list of conditions and the following disclaimer
17// in the documentation and/or other materials provided with the
18// distribution.
19// * Neither the name of Google Inc. nor the names of its
20// contributors may be used to endorse or promote products derived from
21// this software without specific prior written permission.
22//
23// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35#endregion
36
37using System;
38using System.Collections.Generic;
39using Google.ProtocolBuffers.Descriptors;
40using Google.ProtocolBuffers.TestProtos;
csharptesteac64a52011-10-04 13:43:26 -050041using Microsoft.VisualStudio.TestTools.UnitTesting;
csharptest71f662c2011-05-20 15:15:34 -050042
43namespace Google.ProtocolBuffers
44{
csharptesteac64a52011-10-04 13:43:26 -050045 [TestClass]
csharptest71f662c2011-05-20 15:15:34 -050046 public class UnknownFieldSetTest
47 {
48 private MessageDescriptor descriptor;
49 private TestAllTypes allFields;
50 private ByteString allFieldsData;
51
52 /// <summary>
53 /// An empty message that has been parsed from allFieldsData. So, it has
54 /// unknown fields of every type.
55 /// </summary>
56 private TestEmptyMessage emptyMessage;
57
58 private UnknownFieldSet unknownFields;
59
csharptesteac64a52011-10-04 13:43:26 -050060 [TestInitialize]
csharptest71f662c2011-05-20 15:15:34 -050061 public void SetUp()
62 {
63 descriptor = TestAllTypes.Descriptor;
64 allFields = TestUtil.GetAllSet();
65 allFieldsData = allFields.ToByteString();
66 emptyMessage = TestEmptyMessage.ParseFrom(allFieldsData);
67 unknownFields = emptyMessage.UnknownFields;
68 }
69
70 private UnknownField GetField(String name)
71 {
72 FieldDescriptor field = descriptor.FindDescriptor<FieldDescriptor>(name);
73 Assert.IsNotNull(field);
74 return unknownFields.FieldDictionary[field.FieldNumber];
75 }
76
77 /// <summary>
78 /// Constructs a protocol buffer which contains fields with all the same
79 /// numbers as allFieldsData except that each field is some other wire
80 /// type.
81 /// </summary>
82 private ByteString GetBizarroData()
83 {
84 UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.CreateBuilder();
85
86 UnknownField varintField = UnknownField.CreateBuilder().AddVarint(1).Build();
87 UnknownField fixed32Field = UnknownField.CreateBuilder().AddFixed32(1).Build();
88
89 foreach (KeyValuePair<int, UnknownField> entry in unknownFields.FieldDictionary)
90 {
91 if (entry.Value.VarintList.Count == 0)
92 {
93 // Original field is not a varint, so use a varint.
94 bizarroFields.AddField(entry.Key, varintField);
95 }
96 else
97 {
98 // Original field *is* a varint, so use something else.
99 bizarroFields.AddField(entry.Key, fixed32Field);
100 }
101 }
102
103 return bizarroFields.Build().ToByteString();
104 }
105
106 // =================================================================
107
csharptesteac64a52011-10-04 13:43:26 -0500108 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500109 public void Varint()
110 {
111 UnknownField field = GetField("optional_int32");
112 Assert.AreEqual(1, field.VarintList.Count);
113 Assert.AreEqual(allFields.OptionalInt32, (long) field.VarintList[0]);
114 }
115
csharptesteac64a52011-10-04 13:43:26 -0500116 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500117 public void Fixed32()
118 {
119 UnknownField field = GetField("optional_fixed32");
120 Assert.AreEqual(1, field.Fixed32List.Count);
csharptesteac64a52011-10-04 13:43:26 -0500121 Assert.AreEqual<long>(allFields.OptionalFixed32, (int) field.Fixed32List[0]);
csharptest71f662c2011-05-20 15:15:34 -0500122 }
123
csharptesteac64a52011-10-04 13:43:26 -0500124 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500125 public void Fixed64()
126 {
127 UnknownField field = GetField("optional_fixed64");
128 Assert.AreEqual(1, field.Fixed64List.Count);
csharptesteac64a52011-10-04 13:43:26 -0500129 Assert.AreEqual((long)allFields.OptionalFixed64, (long)field.Fixed64List[0]);
csharptest71f662c2011-05-20 15:15:34 -0500130 }
131
csharptesteac64a52011-10-04 13:43:26 -0500132 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500133 public void LengthDelimited()
134 {
135 UnknownField field = GetField("optional_bytes");
136 Assert.AreEqual(1, field.LengthDelimitedList.Count);
137 Assert.AreEqual(allFields.OptionalBytes, field.LengthDelimitedList[0]);
138 }
139
csharptesteac64a52011-10-04 13:43:26 -0500140 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500141 public void Group()
142 {
143 FieldDescriptor nestedFieldDescriptor =
144 TestAllTypes.Types.OptionalGroup.Descriptor.FindDescriptor<FieldDescriptor>("a");
145 Assert.IsNotNull(nestedFieldDescriptor);
146
147 UnknownField field = GetField("optionalgroup");
148 Assert.AreEqual(1, field.GroupList.Count);
149
150 UnknownFieldSet group = field.GroupList[0];
151 Assert.AreEqual(1, group.FieldDictionary.Count);
152 Assert.IsTrue(group.HasField(nestedFieldDescriptor.FieldNumber));
153
154 UnknownField nestedField = group[nestedFieldDescriptor.FieldNumber];
155 Assert.AreEqual(1, nestedField.VarintList.Count);
156 Assert.AreEqual(allFields.OptionalGroup.A, (long) nestedField.VarintList[0]);
157 }
158
csharptesteac64a52011-10-04 13:43:26 -0500159 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500160 public void Serialize()
161 {
162 // Check that serializing the UnknownFieldSet produces the original data again.
163 ByteString data = emptyMessage.ToByteString();
164 Assert.AreEqual(allFieldsData, data);
165 }
166
csharptesteac64a52011-10-04 13:43:26 -0500167 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500168 public void CopyFrom()
169 {
170 TestEmptyMessage message =
171 TestEmptyMessage.CreateBuilder().MergeFrom(emptyMessage).Build();
172
173 Assert.AreEqual(emptyMessage.ToString(), message.ToString());
174 }
175
csharptesteac64a52011-10-04 13:43:26 -0500176 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500177 public void MergeFrom()
178 {
179 TestEmptyMessage source =
180 TestEmptyMessage.CreateBuilder()
181 .SetUnknownFields(
182 UnknownFieldSet.CreateBuilder()
183 .AddField(2,
184 UnknownField.CreateBuilder()
185 .AddVarint(2).Build())
186 .AddField(3,
187 UnknownField.CreateBuilder()
188 .AddVarint(4).Build())
189 .Build())
190 .Build();
191 TestEmptyMessage destination =
192 TestEmptyMessage.CreateBuilder()
193 .SetUnknownFields(
194 UnknownFieldSet.CreateBuilder()
195 .AddField(1,
196 UnknownField.CreateBuilder()
197 .AddVarint(1).Build())
198 .AddField(3,
199 UnknownField.CreateBuilder()
200 .AddVarint(3).Build())
201 .Build())
202 .MergeFrom(source)
203 .Build();
204
205 Assert.AreEqual(
206 "1: 1\n" +
207 "2: 2\n" +
208 "3: 3\n" +
209 "3: 4\n",
210 destination.ToString());
211 }
212
csharptesteac64a52011-10-04 13:43:26 -0500213 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500214 public void Clear()
215 {
216 UnknownFieldSet fields =
217 UnknownFieldSet.CreateBuilder().MergeFrom(unknownFields).Clear().Build();
218 Assert.AreEqual(0, fields.FieldDictionary.Count);
219 }
220
csharptesteac64a52011-10-04 13:43:26 -0500221 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500222 public void ClearMessage()
223 {
224 TestEmptyMessage message =
225 TestEmptyMessage.CreateBuilder().MergeFrom(emptyMessage).Clear().Build();
226 Assert.AreEqual(0, message.SerializedSize);
227 }
228
csharptesteac64a52011-10-04 13:43:26 -0500229 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500230 public void ParseKnownAndUnknown()
231 {
232 // Test mixing known and unknown fields when parsing.
233
234 UnknownFieldSet fields =
235 UnknownFieldSet.CreateBuilder(unknownFields)
236 .AddField(123456,
237 UnknownField.CreateBuilder().AddVarint(654321).Build())
238 .Build();
239
240 ByteString data = fields.ToByteString();
241 TestAllTypes destination = TestAllTypes.ParseFrom(data);
242
243 TestUtil.AssertAllFieldsSet(destination);
244 Assert.AreEqual(1, destination.UnknownFields.FieldDictionary.Count);
245
246 UnknownField field = destination.UnknownFields[123456];
247 Assert.AreEqual(1, field.VarintList.Count);
248 Assert.AreEqual(654321, (long) field.VarintList[0]);
249 }
250
csharptesteac64a52011-10-04 13:43:26 -0500251 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500252 public void WrongTypeTreatedAsUnknown()
253 {
254 // Test that fields of the wrong wire type are treated like unknown fields
255 // when parsing.
256
257 ByteString bizarroData = GetBizarroData();
258 TestAllTypes allTypesMessage = TestAllTypes.ParseFrom(bizarroData);
259 TestEmptyMessage emptyMessage = TestEmptyMessage.ParseFrom(bizarroData);
260
261 // All fields should have been interpreted as unknown, so the debug strings
262 // should be the same.
263 Assert.AreEqual(emptyMessage.ToString(), allTypesMessage.ToString());
264 }
265
csharptesteac64a52011-10-04 13:43:26 -0500266 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500267 public void UnknownExtensions()
268 {
269 // Make sure fields are properly parsed to the UnknownFieldSet even when
270 // they are declared as extension numbers.
271
272 TestEmptyMessageWithExtensions message =
273 TestEmptyMessageWithExtensions.ParseFrom(allFieldsData);
274
275 Assert.AreEqual(unknownFields.FieldDictionary.Count,
276 message.UnknownFields.FieldDictionary.Count);
277 Assert.AreEqual(allFieldsData, message.ToByteString());
278 }
279
csharptesteac64a52011-10-04 13:43:26 -0500280 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500281 public void WrongExtensionTypeTreatedAsUnknown()
282 {
283 // Test that fields of the wrong wire type are treated like unknown fields
284 // when parsing extensions.
285
286 ByteString bizarroData = GetBizarroData();
287 TestAllExtensions allExtensionsMessage = TestAllExtensions.ParseFrom(bizarroData);
288 TestEmptyMessage emptyMessage = TestEmptyMessage.ParseFrom(bizarroData);
289
290 // All fields should have been interpreted as unknown, so the debug strings
291 // should be the same.
292 Assert.AreEqual(emptyMessage.ToString(),
293 allExtensionsMessage.ToString());
294 }
295
csharptesteac64a52011-10-04 13:43:26 -0500296 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500297 public void ParseUnknownEnumValue()
298 {
299 FieldDescriptor singularField =
300 TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("optional_nested_enum");
301 FieldDescriptor repeatedField =
302 TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_nested_enum");
303 Assert.IsNotNull(singularField);
304 Assert.IsNotNull(repeatedField);
305
306 ByteString data =
307 UnknownFieldSet.CreateBuilder()
308 .AddField(singularField.FieldNumber,
309 UnknownField.CreateBuilder()
310 .AddVarint((int) TestAllTypes.Types.NestedEnum.BAR)
311 .AddVarint(5) // not valid
312 .Build())
313 .AddField(repeatedField.FieldNumber,
314 UnknownField.CreateBuilder()
315 .AddVarint((int) TestAllTypes.Types.NestedEnum.FOO)
316 .AddVarint(4) // not valid
317 .AddVarint((int) TestAllTypes.Types.NestedEnum.BAZ)
318 .AddVarint(6) // not valid
319 .Build())
320 .Build()
321 .ToByteString();
322
323 {
324 TestAllTypes message = TestAllTypes.ParseFrom(data);
325 Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR,
326 message.OptionalNestedEnum);
327 TestUtil.AssertEqual(new[] {TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.BAZ},
328 message.RepeatedNestedEnumList);
329 TestUtil.AssertEqual(new[] {5UL}, message.UnknownFields[singularField.FieldNumber].VarintList);
330 TestUtil.AssertEqual(new[] {4UL, 6UL}, message.UnknownFields[repeatedField.FieldNumber].VarintList);
331 }
332
333 {
334 TestAllExtensions message =
335 TestAllExtensions.ParseFrom(data, TestUtil.CreateExtensionRegistry());
336 Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR,
337 message.GetExtension(UnitTestProtoFile.OptionalNestedEnumExtension));
338 TestUtil.AssertEqual(new[] {TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.BAZ},
339 message.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension));
340 TestUtil.AssertEqual(new[] {5UL}, message.UnknownFields[singularField.FieldNumber].VarintList);
341 TestUtil.AssertEqual(new[] {4UL, 6UL}, message.UnknownFields[repeatedField.FieldNumber].VarintList);
342 }
343 }
344
csharptesteac64a52011-10-04 13:43:26 -0500345 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500346 public void LargeVarint()
347 {
348 ByteString data =
349 UnknownFieldSet.CreateBuilder()
350 .AddField(1,
351 UnknownField.CreateBuilder()
352 .AddVarint(0x7FFFFFFFFFFFFFFFL)
353 .Build())
354 .Build()
355 .ToByteString();
356 UnknownFieldSet parsed = UnknownFieldSet.ParseFrom(data);
357 UnknownField field = parsed[1];
358 Assert.AreEqual(1, field.VarintList.Count);
359 Assert.AreEqual(0x7FFFFFFFFFFFFFFFUL, field.VarintList[0]);
360 }
361
csharptesteac64a52011-10-04 13:43:26 -0500362 [TestMethod]
csharptest71f662c2011-05-20 15:15:34 -0500363 public void EqualsAndHashCode()
364 {
365 UnknownField fixed32Field = UnknownField.CreateBuilder().AddFixed32(1).Build();
366 UnknownField fixed64Field = UnknownField.CreateBuilder().AddFixed64(1).Build();
367 UnknownField varIntField = UnknownField.CreateBuilder().AddVarint(1).Build();
368 UnknownField lengthDelimitedField =
369 UnknownField.CreateBuilder().AddLengthDelimited(ByteString.Empty).Build();
370 UnknownField groupField = UnknownField.CreateBuilder().AddGroup(unknownFields).Build();
371
372 UnknownFieldSet a = UnknownFieldSet.CreateBuilder().AddField(1, fixed32Field).Build();
373 UnknownFieldSet b = UnknownFieldSet.CreateBuilder().AddField(1, fixed64Field).Build();
374 UnknownFieldSet c = UnknownFieldSet.CreateBuilder().AddField(1, varIntField).Build();
375 UnknownFieldSet d = UnknownFieldSet.CreateBuilder().AddField(1, lengthDelimitedField).Build();
376 UnknownFieldSet e = UnknownFieldSet.CreateBuilder().AddField(1, groupField).Build();
377
378 CheckEqualsIsConsistent(a);
379 CheckEqualsIsConsistent(b);
380 CheckEqualsIsConsistent(c);
381 CheckEqualsIsConsistent(d);
382 CheckEqualsIsConsistent(e);
383
384 CheckNotEqual(a, b);
385 CheckNotEqual(a, c);
386 CheckNotEqual(a, d);
387 CheckNotEqual(a, e);
388 CheckNotEqual(b, c);
389 CheckNotEqual(b, d);
390 CheckNotEqual(b, e);
391 CheckNotEqual(c, d);
392 CheckNotEqual(c, e);
393 CheckNotEqual(d, e);
394 }
395
396 /// <summary>
397 /// Asserts that the given field sets are not equal and have different
398 /// hash codes.
399 /// </summary>
400 /// <remarks>
401 /// It's valid for non-equal objects to have the same hash code, so
402 /// this test is stricter than it needs to be. However, this should happen
403 /// relatively rarely.
404 /// </remarks>
405 /// <param name="s1"></param>
406 /// <param name="s2"></param>
407 private static void CheckNotEqual(UnknownFieldSet s1, UnknownFieldSet s2)
408 {
409 String equalsError = string.Format("{0} should not be equal to {1}", s1, s2);
410 Assert.IsFalse(s1.Equals(s2), equalsError);
411 Assert.IsFalse(s2.Equals(s1), equalsError);
412
413 Assert.IsFalse(s1.GetHashCode() == s2.GetHashCode(),
414 string.Format("{0} should have a different hash code from {1}", s1, s2));
415 }
416
417 /**
418 * Asserts that the given field sets are equal and have identical hash codes.
419 */
420
421 private static void CheckEqualsIsConsistent(UnknownFieldSet set)
422 {
423 // Object should be equal to itself.
424 Assert.AreEqual(set, set);
425
426 // Object should be equal to a copy of itself.
427 UnknownFieldSet copy = UnknownFieldSet.CreateBuilder(set).Build();
428 Assert.AreEqual(set, copy);
429 Assert.AreEqual(copy, set);
430 Assert.AreEqual(set.GetHashCode(), copy.GetHashCode());
431 }
432 }
433}