Jon Skeet | 6803686 | 2008-10-22 13:30:34 +0100 | [diff] [blame^] | 1 | // Protocol Buffers - Google's data interchange format |
| 2 | // Copyright 2008 Google Inc. |
| 3 | // http://code.google.com/p/protobuf/ |
| 4 | // |
| 5 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | // you may not use this file except in compliance with the License. |
| 7 | // You may obtain a copy of the License at |
| 8 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // |
| 11 | // Unless required by applicable law or agreed to in writing, software |
| 12 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | // See the License for the specific language governing permissions and |
| 15 | // limitations under the License. |
| 16 | using System; |
| 17 | using System.Collections.Generic; |
| 18 | using Google.ProtocolBuffers.Descriptors; |
| 19 | using Google.ProtocolBuffers.TestProtos; |
| 20 | using NUnit.Framework; |
| 21 | |
| 22 | namespace Google.ProtocolBuffers { |
| 23 | [TestFixture] |
| 24 | public class UnknownFieldSetTest { |
| 25 | |
| 26 | private MessageDescriptor descriptor; |
| 27 | private TestAllTypes allFields; |
| 28 | private ByteString allFieldsData; |
| 29 | |
| 30 | /// <summary> |
| 31 | /// An empty message that has been parsed from allFieldsData. So, it has |
| 32 | /// unknown fields of every type. |
| 33 | /// </summary> |
| 34 | private TestEmptyMessage emptyMessage; |
| 35 | private UnknownFieldSet unknownFields; |
| 36 | |
| 37 | [SetUp] |
| 38 | public void SetUp() { |
| 39 | descriptor = TestAllTypes.Descriptor; |
| 40 | allFields = TestUtil.GetAllSet(); |
| 41 | allFieldsData = allFields.ToByteString(); |
| 42 | emptyMessage = TestEmptyMessage.ParseFrom(allFieldsData); |
| 43 | unknownFields = emptyMessage.UnknownFields; |
| 44 | } |
| 45 | |
| 46 | private UnknownField GetField(String name) { |
| 47 | FieldDescriptor field = descriptor.FindDescriptor<FieldDescriptor>(name); |
| 48 | Assert.IsNotNull(field); |
| 49 | return unknownFields.FieldDictionary[field.FieldNumber]; |
| 50 | } |
| 51 | |
| 52 | /// <summary> |
| 53 | /// Constructs a protocol buffer which contains fields with all the same |
| 54 | /// numbers as allFieldsData except that each field is some other wire |
| 55 | /// type. |
| 56 | /// </summary> |
| 57 | private ByteString GetBizarroData() { |
| 58 | UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.CreateBuilder(); |
| 59 | |
| 60 | UnknownField varintField = UnknownField.CreateBuilder().AddVarint(1).Build(); |
| 61 | UnknownField fixed32Field = UnknownField.CreateBuilder().AddFixed32(1).Build(); |
| 62 | |
| 63 | foreach (KeyValuePair<int, UnknownField> entry in unknownFields.FieldDictionary) { |
| 64 | if (entry.Value.VarintList.Count == 0) { |
| 65 | // Original field is not a varint, so use a varint. |
| 66 | bizarroFields.AddField(entry.Key, varintField); |
| 67 | } else { |
| 68 | // Original field *is* a varint, so use something else. |
| 69 | bizarroFields.AddField(entry.Key, fixed32Field); |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | return bizarroFields.Build().ToByteString(); |
| 74 | } |
| 75 | |
| 76 | // ================================================================= |
| 77 | |
| 78 | [Test] |
| 79 | public void Varint() { |
| 80 | UnknownField field = GetField("optional_int32"); |
| 81 | Assert.AreEqual(1, field.VarintList.Count); |
| 82 | Assert.AreEqual(allFields.OptionalInt32, (long) field.VarintList[0]); |
| 83 | } |
| 84 | |
| 85 | [Test] |
| 86 | public void Fixed32() { |
| 87 | UnknownField field = GetField("optional_fixed32"); |
| 88 | Assert.AreEqual(1, field.Fixed32List.Count); |
| 89 | Assert.AreEqual(allFields.OptionalFixed32, (int) field.Fixed32List[0]); |
| 90 | } |
| 91 | |
| 92 | [Test] |
| 93 | public void Fixed64() { |
| 94 | UnknownField field = GetField("optional_fixed64"); |
| 95 | Assert.AreEqual(1, field.Fixed64List.Count); |
| 96 | Assert.AreEqual(allFields.OptionalFixed64, (long) field.Fixed64List[0]); |
| 97 | } |
| 98 | |
| 99 | [Test] |
| 100 | public void LengthDelimited() { |
| 101 | UnknownField field = GetField("optional_bytes"); |
| 102 | Assert.AreEqual(1, field.LengthDelimitedList.Count); |
| 103 | Assert.AreEqual(allFields.OptionalBytes, field.LengthDelimitedList[0]); |
| 104 | } |
| 105 | |
| 106 | [Test] |
| 107 | public void Group() { |
| 108 | FieldDescriptor nestedFieldDescriptor = |
| 109 | TestAllTypes.Types.OptionalGroup.Descriptor.FindDescriptor<FieldDescriptor>("a"); |
| 110 | Assert.IsNotNull(nestedFieldDescriptor); |
| 111 | |
| 112 | UnknownField field = GetField("optionalgroup"); |
| 113 | Assert.AreEqual(1, field.GroupList.Count); |
| 114 | |
| 115 | UnknownFieldSet group = field.GroupList[0]; |
| 116 | Assert.AreEqual(1, group.FieldDictionary.Count); |
| 117 | Assert.IsTrue(group.HasField(nestedFieldDescriptor.FieldNumber)); |
| 118 | |
| 119 | UnknownField nestedField = group[nestedFieldDescriptor.FieldNumber]; |
| 120 | Assert.AreEqual(1, nestedField.VarintList.Count); |
| 121 | Assert.AreEqual(allFields.OptionalGroup.A, (long) nestedField.VarintList[0]); |
| 122 | } |
| 123 | |
| 124 | [Test] |
| 125 | public void Serialize() { |
| 126 | // Check that serializing the UnknownFieldSet produces the original data again. |
| 127 | ByteString data = emptyMessage.ToByteString(); |
| 128 | Assert.AreEqual(allFieldsData, data); |
| 129 | } |
| 130 | |
| 131 | [Test] |
| 132 | public void CopyFrom() { |
| 133 | TestEmptyMessage message = |
| 134 | TestEmptyMessage.CreateBuilder().MergeFrom(emptyMessage).Build(); |
| 135 | |
| 136 | Assert.AreEqual(emptyMessage.ToString(), message.ToString()); |
| 137 | } |
| 138 | |
| 139 | [Test] |
| 140 | public void MergeFrom() { |
| 141 | TestEmptyMessage source = |
| 142 | TestEmptyMessage.CreateBuilder() |
| 143 | .SetUnknownFields( |
| 144 | UnknownFieldSet.CreateBuilder() |
| 145 | .AddField(2, |
| 146 | UnknownField.CreateBuilder() |
| 147 | .AddVarint(2).Build()) |
| 148 | .AddField(3, |
| 149 | UnknownField.CreateBuilder() |
| 150 | .AddVarint(4).Build()) |
| 151 | .Build()) |
| 152 | .Build(); |
| 153 | TestEmptyMessage destination = |
| 154 | TestEmptyMessage.CreateBuilder() |
| 155 | .SetUnknownFields( |
| 156 | UnknownFieldSet.CreateBuilder() |
| 157 | .AddField(1, |
| 158 | UnknownField.CreateBuilder() |
| 159 | .AddVarint(1).Build()) |
| 160 | .AddField(3, |
| 161 | UnknownField.CreateBuilder() |
| 162 | .AddVarint(3).Build()) |
| 163 | .Build()) |
| 164 | .MergeFrom(source) |
| 165 | .Build(); |
| 166 | |
| 167 | Assert.AreEqual( |
| 168 | "1: 1\n" + |
| 169 | "2: 2\n" + |
| 170 | "3: 3\n" + |
| 171 | "3: 4\n", |
| 172 | destination.ToString()); |
| 173 | } |
| 174 | |
| 175 | [Test] |
| 176 | public void Clear() { |
| 177 | UnknownFieldSet fields = |
| 178 | UnknownFieldSet.CreateBuilder().MergeFrom(unknownFields).Clear().Build(); |
| 179 | Assert.AreEqual(0, fields.FieldDictionary.Count); |
| 180 | } |
| 181 | |
| 182 | [Test] |
| 183 | public void ClearMessage() { |
| 184 | TestEmptyMessage message = |
| 185 | TestEmptyMessage.CreateBuilder().MergeFrom(emptyMessage).Clear().Build(); |
| 186 | Assert.AreEqual(0, message.SerializedSize); |
| 187 | } |
| 188 | |
| 189 | [Test] |
| 190 | public void ParseKnownAndUnknown() { |
| 191 | // Test mixing known and unknown fields when parsing. |
| 192 | |
| 193 | UnknownFieldSet fields = |
| 194 | UnknownFieldSet.CreateBuilder(unknownFields) |
| 195 | .AddField(123456, |
| 196 | UnknownField.CreateBuilder().AddVarint(654321).Build()) |
| 197 | .Build(); |
| 198 | |
| 199 | ByteString data = fields.ToByteString(); |
| 200 | TestAllTypes destination = TestAllTypes.ParseFrom(data); |
| 201 | |
| 202 | TestUtil.AssertAllFieldsSet(destination); |
| 203 | Assert.AreEqual(1, destination.UnknownFields.FieldDictionary.Count); |
| 204 | |
| 205 | UnknownField field = destination.UnknownFields[123456]; |
| 206 | Assert.AreEqual(1, field.VarintList.Count); |
| 207 | Assert.AreEqual(654321, (long) field.VarintList[0]); |
| 208 | } |
| 209 | |
| 210 | [Test] |
| 211 | public void WrongTypeTreatedAsUnknown() { |
| 212 | // Test that fields of the wrong wire type are treated like unknown fields |
| 213 | // when parsing. |
| 214 | |
| 215 | ByteString bizarroData = GetBizarroData(); |
| 216 | TestAllTypes allTypesMessage = TestAllTypes.ParseFrom(bizarroData); |
| 217 | TestEmptyMessage emptyMessage = TestEmptyMessage.ParseFrom(bizarroData); |
| 218 | |
| 219 | // All fields should have been interpreted as unknown, so the debug strings |
| 220 | // should be the same. |
| 221 | Assert.AreEqual(emptyMessage.ToString(), allTypesMessage.ToString()); |
| 222 | } |
| 223 | |
| 224 | [Test] |
| 225 | public void UnknownExtensions() { |
| 226 | // Make sure fields are properly parsed to the UnknownFieldSet even when |
| 227 | // they are declared as extension numbers. |
| 228 | |
| 229 | TestEmptyMessageWithExtensions message = |
| 230 | TestEmptyMessageWithExtensions.ParseFrom(allFieldsData); |
| 231 | |
| 232 | Assert.AreEqual(unknownFields.FieldDictionary.Count, |
| 233 | message.UnknownFields.FieldDictionary.Count); |
| 234 | Assert.AreEqual(allFieldsData, message.ToByteString()); |
| 235 | } |
| 236 | |
| 237 | [Test] |
| 238 | public void WrongExtensionTypeTreatedAsUnknown() { |
| 239 | // Test that fields of the wrong wire type are treated like unknown fields |
| 240 | // when parsing extensions. |
| 241 | |
| 242 | ByteString bizarroData = GetBizarroData(); |
| 243 | TestAllExtensions allExtensionsMessage = TestAllExtensions.ParseFrom(bizarroData); |
| 244 | TestEmptyMessage emptyMessage = TestEmptyMessage.ParseFrom(bizarroData); |
| 245 | |
| 246 | // All fields should have been interpreted as unknown, so the debug strings |
| 247 | // should be the same. |
| 248 | Assert.AreEqual(emptyMessage.ToString(), |
| 249 | allExtensionsMessage.ToString()); |
| 250 | } |
| 251 | |
| 252 | [Test] |
| 253 | public void ParseUnknownEnumValue() { |
| 254 | FieldDescriptor singularField = TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("optional_nested_enum"); |
| 255 | FieldDescriptor repeatedField = TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_nested_enum"); |
| 256 | Assert.IsNotNull(singularField); |
| 257 | Assert.IsNotNull(repeatedField); |
| 258 | |
| 259 | ByteString data = |
| 260 | UnknownFieldSet.CreateBuilder() |
| 261 | .AddField(singularField.FieldNumber, |
| 262 | UnknownField.CreateBuilder() |
| 263 | .AddVarint((int) TestAllTypes.Types.NestedEnum.BAR) |
| 264 | .AddVarint(5) // not valid |
| 265 | .Build()) |
| 266 | .AddField(repeatedField.FieldNumber, |
| 267 | UnknownField.CreateBuilder() |
| 268 | .AddVarint((int) TestAllTypes.Types.NestedEnum.FOO) |
| 269 | .AddVarint(4) // not valid |
| 270 | .AddVarint((int) TestAllTypes.Types.NestedEnum.BAZ) |
| 271 | .AddVarint(6) // not valid |
| 272 | .Build()) |
| 273 | .Build() |
| 274 | .ToByteString(); |
| 275 | |
| 276 | { |
| 277 | TestAllTypes message = TestAllTypes.ParseFrom(data); |
| 278 | Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, |
| 279 | message.OptionalNestedEnum); |
| 280 | TestUtil.AssertEqual(new [] {TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.BAZ}, |
| 281 | message.RepeatedNestedEnumList); |
| 282 | TestUtil.AssertEqual(new[] {5UL}, message.UnknownFields[singularField.FieldNumber].VarintList); |
| 283 | TestUtil.AssertEqual(new[] {4UL, 6UL}, message.UnknownFields[repeatedField.FieldNumber].VarintList); |
| 284 | } |
| 285 | |
| 286 | { |
| 287 | TestAllExtensions message = |
| 288 | TestAllExtensions.ParseFrom(data, TestUtil.CreateExtensionRegistry()); |
| 289 | Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, |
| 290 | message.GetExtension(UnitTestProtoFile.OptionalNestedEnumExtension)); |
| 291 | TestUtil.AssertEqual(new[] { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.BAZ }, |
| 292 | message.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension)); |
| 293 | TestUtil.AssertEqual(new[] { 5UL }, message.UnknownFields[singularField.FieldNumber].VarintList); |
| 294 | TestUtil.AssertEqual(new[] { 4UL, 6UL }, message.UnknownFields[repeatedField.FieldNumber].VarintList); |
| 295 | } |
| 296 | } |
| 297 | |
| 298 | [Test] |
| 299 | public void LargeVarint() { |
| 300 | ByteString data = |
| 301 | UnknownFieldSet.CreateBuilder() |
| 302 | .AddField(1, |
| 303 | UnknownField.CreateBuilder() |
| 304 | .AddVarint(0x7FFFFFFFFFFFFFFFL) |
| 305 | .Build()) |
| 306 | .Build() |
| 307 | .ToByteString(); |
| 308 | UnknownFieldSet parsed = UnknownFieldSet.ParseFrom(data); |
| 309 | UnknownField field = parsed[1]; |
| 310 | Assert.AreEqual(1, field.VarintList.Count); |
| 311 | Assert.AreEqual(0x7FFFFFFFFFFFFFFFUL, field.VarintList[0]); |
| 312 | } |
| 313 | } |
| 314 | } |