1 #region Copyright notice and license 2 // Protocol Buffers - Google's data interchange format 3 // Copyright 2008 Google Inc. All rights reserved. 4 // https://developers.google.com/protocol-buffers/ 5 // 6 // Redistribution and use in source and binary forms, with or without 7 // modification, are permitted provided that the following conditions are 8 // met: 9 // 10 // * Redistributions of source code must retain the above copyright 11 // notice, this list of conditions and the following disclaimer. 12 // * Redistributions in binary form must reproduce the above 13 // copyright notice, this list of conditions and the following disclaimer 14 // in the documentation and/or other materials provided with the 15 // distribution. 16 // * Neither the name of Google Inc. nor the names of its 17 // contributors may be used to endorse or promote products derived from 18 // this software without specific prior written permission. 19 // 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 #endregion 32 33 using System; 34 using System.IO; 35 using Google.Protobuf.TestProtos; 36 using Proto2 = Google.Protobuf.TestProtos.Proto2; 37 using NUnit.Framework; 38 39 namespace Google.Protobuf 40 { 41 public class UnknownFieldSetTest 42 { 43 public class Data 44 { 45 public static System.Collections.IEnumerable Messages 46 { 47 get 48 { 49 yield return SampleMessages.CreateFullTestAllTypesProto2(); 50 yield return SampleMessages.CreateFullTestAllTypes(); 51 } 52 } 53 } 54 55 [Test] EmptyUnknownFieldSet()56 public void EmptyUnknownFieldSet() 57 { 58 UnknownFieldSet unknownFields = new UnknownFieldSet(); 59 Assert.AreEqual(0, unknownFields.CalculateSize()); 60 } 61 62 [Test] MergeUnknownFieldSet()63 public void MergeUnknownFieldSet() 64 { 65 UnknownFieldSet unknownFields = new UnknownFieldSet(); 66 UnknownField field = new UnknownField(); 67 field.AddFixed32(123); 68 unknownFields.AddOrReplaceField(1, field); 69 UnknownFieldSet otherUnknownFields = new UnknownFieldSet(); 70 Assert.IsFalse(otherUnknownFields.HasField(1)); 71 UnknownFieldSet.MergeFrom(otherUnknownFields, unknownFields); 72 Assert.IsTrue(otherUnknownFields.HasField(1)); 73 } 74 75 [Test] 76 [TestCaseSource(typeof(Data), "Messages")] TestMergeCodedInput(IMessage message)77 public void TestMergeCodedInput(IMessage message) 78 { 79 var emptyMessage = new TestEmptyMessage(); 80 emptyMessage.MergeFrom(message.ToByteArray()); 81 Assert.AreEqual(message.CalculateSize(), emptyMessage.CalculateSize()); 82 Assert.AreEqual(message.ToByteArray(), emptyMessage.ToByteArray()); 83 84 var newMessage = message.Descriptor.Parser.ParseFrom(emptyMessage.ToByteArray()); 85 Assert.AreEqual(message, newMessage); 86 Assert.AreEqual(message.CalculateSize(), newMessage.CalculateSize()); 87 } 88 89 [Test] 90 [TestCaseSource(typeof(Data), "Messages")] TestMergeMessage(IMessage message)91 public void TestMergeMessage(IMessage message) 92 { 93 var emptyMessage = new TestEmptyMessage(); 94 var otherEmptyMessage = new TestEmptyMessage(); 95 emptyMessage.MergeFrom(message.ToByteArray()); 96 otherEmptyMessage.MergeFrom(emptyMessage); 97 98 Assert.AreEqual(message.CalculateSize(), otherEmptyMessage.CalculateSize()); 99 Assert.AreEqual(message.ToByteArray(), otherEmptyMessage.ToByteArray()); 100 } 101 102 [Test] 103 [TestCaseSource(typeof(Data), "Messages")] TestEquals(IMessage message)104 public void TestEquals(IMessage message) 105 { 106 var emptyMessage = new TestEmptyMessage(); 107 var otherEmptyMessage = new TestEmptyMessage(); 108 Assert.AreEqual(emptyMessage, otherEmptyMessage); 109 emptyMessage.MergeFrom(message.ToByteArray()); 110 Assert.AreNotEqual(emptyMessage.CalculateSize(), 111 otherEmptyMessage.CalculateSize()); 112 Assert.AreNotEqual(emptyMessage, otherEmptyMessage); 113 } 114 115 [Test] 116 [TestCaseSource(typeof(Data), "Messages")] TestHashCode(IMessage message)117 public void TestHashCode(IMessage message) 118 { 119 var emptyMessage = new TestEmptyMessage(); 120 int hashCode = emptyMessage.GetHashCode(); 121 emptyMessage.MergeFrom(message.ToByteArray()); 122 Assert.AreNotEqual(hashCode, emptyMessage.GetHashCode()); 123 } 124 125 [Test] 126 [TestCaseSource(typeof(Data), "Messages")] TestClone(IMessage message)127 public void TestClone(IMessage message) 128 { 129 var emptyMessage = new TestEmptyMessage(); 130 var otherEmptyMessage = new TestEmptyMessage(); 131 otherEmptyMessage = emptyMessage.Clone(); 132 Assert.AreEqual(emptyMessage.CalculateSize(), otherEmptyMessage.CalculateSize()); 133 Assert.AreEqual(emptyMessage.ToByteArray(), otherEmptyMessage.ToByteArray()); 134 135 emptyMessage.MergeFrom(message.ToByteArray()); 136 otherEmptyMessage = emptyMessage.Clone(); 137 Assert.AreEqual(message.CalculateSize(), otherEmptyMessage.CalculateSize()); 138 Assert.AreEqual(message.ToByteArray(), otherEmptyMessage.ToByteArray()); 139 } 140 141 [Test] 142 [TestCaseSource(typeof(Data), "Messages")] TestDiscardUnknownFields(IMessage message)143 public void TestDiscardUnknownFields(IMessage message) 144 { 145 var goldenEmptyMessage = new TestEmptyMessage(); 146 byte[] data = message.ToByteArray(); 147 int fullSize = message.CalculateSize(); 148 149 Action<IMessage> assertEmpty = msg => 150 { 151 Assert.AreEqual(0, msg.CalculateSize()); 152 Assert.AreEqual(goldenEmptyMessage, msg); 153 }; 154 155 Action<IMessage> assertFull = msg => Assert.AreEqual(fullSize, msg.CalculateSize()); 156 157 // Test the behavior of the parsers with and without discarding, both generic and non-generic. 158 MessageParser<TestEmptyMessage> retainingParser1 = TestEmptyMessage.Parser; 159 MessageParser retainingParser2 = retainingParser1; 160 MessageParser<TestEmptyMessage> discardingParser1 = retainingParser1.WithDiscardUnknownFields(true); 161 MessageParser discardingParser2 = retainingParser2.WithDiscardUnknownFields(true); 162 163 // Test parse from byte[] 164 MessageParsingHelpers.AssertReadingMessage(retainingParser1, data, m => assertFull(m)); 165 MessageParsingHelpers.AssertReadingMessage(retainingParser2, data, m => assertFull(m)); 166 MessageParsingHelpers.AssertReadingMessage(discardingParser1, data, m => assertEmpty(m)); 167 MessageParsingHelpers.AssertReadingMessage(discardingParser2, data, m => assertEmpty(m)); 168 169 // Test parse from byte[] with offset 170 assertFull(retainingParser1.ParseFrom(data, 0, data.Length)); 171 assertFull(retainingParser2.ParseFrom(data, 0, data.Length)); 172 assertEmpty(discardingParser1.ParseFrom(data, 0, data.Length)); 173 assertEmpty(discardingParser2.ParseFrom(data, 0, data.Length)); 174 175 // Test parse from CodedInputStream 176 assertFull(retainingParser1.ParseFrom(new CodedInputStream(data))); 177 assertFull(retainingParser2.ParseFrom(new CodedInputStream(data))); 178 assertEmpty(discardingParser1.ParseFrom(new CodedInputStream(data))); 179 assertEmpty(discardingParser2.ParseFrom(new CodedInputStream(data))); 180 181 // Test parse from Stream 182 assertFull(retainingParser1.ParseFrom(new MemoryStream(data))); 183 assertFull(retainingParser2.ParseFrom(new MemoryStream(data))); 184 assertEmpty(discardingParser1.ParseFrom(new MemoryStream(data))); 185 assertEmpty(discardingParser2.ParseFrom(new MemoryStream(data))); 186 } 187 188 [Test] TestReadInvalidWireTypeThrowsInvalidProtocolBufferException()189 public void TestReadInvalidWireTypeThrowsInvalidProtocolBufferException() 190 { 191 MemoryStream ms = new MemoryStream(); 192 CodedOutputStream output = new CodedOutputStream(ms); 193 194 uint tag = WireFormat.MakeTag(1, (WireFormat.WireType)6); 195 output.WriteRawVarint32(tag); 196 output.WriteLength(-1); 197 output.Flush(); 198 ms.Position = 0; 199 200 CodedInputStream input = new CodedInputStream(ms); 201 Assert.AreEqual(tag, input.ReadTag()); 202 203 Assert.Throws<InvalidProtocolBufferException>(() => UnknownFieldSet.MergeFieldFrom(null, input)); 204 } 205 } 206 } 207