1 #region Copyright notice and license 2 3 // Copyright 2019 The gRPC Authors 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 17 #endregion 18 19 using System; 20 using System.Buffers; 21 using System.Collections.Generic; 22 using System.Runtime.InteropServices; 23 using Grpc.Core; 24 using Grpc.Core.Internal; 25 using Grpc.Core.Utils; 26 using NUnit.Framework; 27 28 namespace Grpc.Core.Internal.Tests 29 { 30 public class DefaultDeserializationContextTest 31 { 32 FakeBufferReaderManager fakeBufferReaderManager; 33 34 [SetUp] Init()35 public void Init() 36 { 37 fakeBufferReaderManager = new FakeBufferReaderManager(); 38 } 39 40 [TearDown] Cleanup()41 public void Cleanup() 42 { 43 fakeBufferReaderManager.Dispose(); 44 } 45 46 [TestCase] PayloadAsReadOnlySequence_ZeroSegmentPayload()47 public void PayloadAsReadOnlySequence_ZeroSegmentPayload() 48 { 49 var context = new DefaultDeserializationContext(); 50 context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List<byte[]> {})); 51 52 Assert.AreEqual(0, context.PayloadLength); 53 54 var sequence = context.PayloadAsReadOnlySequence(); 55 56 Assert.AreEqual(ReadOnlySequence<byte>.Empty, sequence); 57 Assert.IsTrue(sequence.IsEmpty); 58 Assert.IsTrue(sequence.IsSingleSegment); 59 } 60 61 [TestCase(0)] 62 [TestCase(1)] 63 [TestCase(10)] 64 [TestCase(100)] 65 [TestCase(1000)] PayloadAsReadOnlySequence_SingleSegmentPayload(int segmentLength)66 public void PayloadAsReadOnlySequence_SingleSegmentPayload(int segmentLength) 67 { 68 var origBuffer = GetTestBuffer(segmentLength); 69 var context = new DefaultDeserializationContext(); 70 context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer)); 71 72 Assert.AreEqual(origBuffer.Length, context.PayloadLength); 73 74 var sequence = context.PayloadAsReadOnlySequence(); 75 76 Assert.AreEqual(origBuffer.Length, sequence.Length); 77 Assert.AreEqual(origBuffer.Length, sequence.First.Length); 78 Assert.IsTrue(sequence.IsSingleSegment); 79 CollectionAssert.AreEqual(origBuffer, sequence.First.ToArray()); 80 } 81 82 [TestCase(0, 5, 10)] 83 [TestCase(1, 1, 1)] 84 [TestCase(10, 100, 1000)] 85 [TestCase(100, 100, 10)] 86 [TestCase(1000, 1000, 1000)] PayloadAsReadOnlySequence_MultiSegmentPayload(int segmentLen1, int segmentLen2, int segmentLen3)87 public void PayloadAsReadOnlySequence_MultiSegmentPayload(int segmentLen1, int segmentLen2, int segmentLen3) 88 { 89 var origBuffer1 = GetTestBuffer(segmentLen1); 90 var origBuffer2 = GetTestBuffer(segmentLen2); 91 var origBuffer3 = GetTestBuffer(segmentLen3); 92 int totalLen = origBuffer1.Length + origBuffer2.Length + origBuffer3.Length; 93 94 var context = new DefaultDeserializationContext(); 95 context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List<byte[]> { origBuffer1, origBuffer2, origBuffer3 })); 96 97 Assert.AreEqual(totalLen, context.PayloadLength); 98 99 var sequence = context.PayloadAsReadOnlySequence(); 100 101 Assert.AreEqual(totalLen, sequence.Length); 102 103 var segmentEnumerator = sequence.GetEnumerator(); 104 105 Assert.IsTrue(segmentEnumerator.MoveNext()); 106 CollectionAssert.AreEqual(origBuffer1, segmentEnumerator.Current.ToArray()); 107 108 Assert.IsTrue(segmentEnumerator.MoveNext()); 109 CollectionAssert.AreEqual(origBuffer2, segmentEnumerator.Current.ToArray()); 110 111 Assert.IsTrue(segmentEnumerator.MoveNext()); 112 CollectionAssert.AreEqual(origBuffer3, segmentEnumerator.Current.ToArray()); 113 114 Assert.IsFalse(segmentEnumerator.MoveNext()); 115 } 116 117 [TestCase] NullPayloadNotAllowed()118 public void NullPayloadNotAllowed() 119 { 120 var context = new DefaultDeserializationContext(); 121 Assert.Throws(typeof(InvalidOperationException), () => context.Initialize(fakeBufferReaderManager.CreateNullPayloadBufferReader())); 122 } 123 124 [TestCase] PayloadAsNewByteBuffer_ZeroSegmentPayload()125 public void PayloadAsNewByteBuffer_ZeroSegmentPayload() 126 { 127 var context = new DefaultDeserializationContext(); 128 context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List<byte[]> {})); 129 130 Assert.AreEqual(0, context.PayloadLength); 131 132 var payload = context.PayloadAsNewBuffer(); 133 Assert.AreEqual(0, payload.Length); 134 } 135 136 [TestCase(0)] 137 [TestCase(1)] 138 [TestCase(10)] 139 [TestCase(100)] 140 [TestCase(1000)] PayloadAsNewByteBuffer_SingleSegmentPayload(int segmentLength)141 public void PayloadAsNewByteBuffer_SingleSegmentPayload(int segmentLength) 142 { 143 var origBuffer = GetTestBuffer(segmentLength); 144 var context = new DefaultDeserializationContext(); 145 context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer)); 146 147 Assert.AreEqual(origBuffer.Length, context.PayloadLength); 148 149 var payload = context.PayloadAsNewBuffer(); 150 CollectionAssert.AreEqual(origBuffer, payload); 151 } 152 153 [TestCase(0, 5, 10)] 154 [TestCase(1, 1, 1)] 155 [TestCase(10, 100, 1000)] 156 [TestCase(100, 100, 10)] 157 [TestCase(1000, 1000, 1000)] PayloadAsNewByteBuffer_MultiSegmentPayload(int segmentLen1, int segmentLen2, int segmentLen3)158 public void PayloadAsNewByteBuffer_MultiSegmentPayload(int segmentLen1, int segmentLen2, int segmentLen3) 159 { 160 var origBuffer1 = GetTestBuffer(segmentLen1); 161 var origBuffer2 = GetTestBuffer(segmentLen2); 162 var origBuffer3 = GetTestBuffer(segmentLen3); 163 164 var context = new DefaultDeserializationContext(); 165 context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List<byte[]> { origBuffer1, origBuffer2, origBuffer3 })); 166 167 var payload = context.PayloadAsNewBuffer(); 168 169 var concatenatedOrigBuffers = new List<byte>(); 170 concatenatedOrigBuffers.AddRange(origBuffer1); 171 concatenatedOrigBuffers.AddRange(origBuffer2); 172 concatenatedOrigBuffers.AddRange(origBuffer3); 173 174 Assert.AreEqual(concatenatedOrigBuffers.Count, context.PayloadLength); 175 Assert.AreEqual(concatenatedOrigBuffers.Count, payload.Length); 176 CollectionAssert.AreEqual(concatenatedOrigBuffers, payload); 177 } 178 179 [TestCase] GetPayloadMultipleTimesIsIllegal()180 public void GetPayloadMultipleTimesIsIllegal() 181 { 182 var origBuffer = GetTestBuffer(100); 183 var context = new DefaultDeserializationContext(); 184 context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer)); 185 186 Assert.AreEqual(origBuffer.Length, context.PayloadLength); 187 188 var payload = context.PayloadAsNewBuffer(); 189 CollectionAssert.AreEqual(origBuffer, payload); 190 191 // Getting payload multiple times is illegal 192 Assert.Throws(typeof(InvalidOperationException), () => context.PayloadAsNewBuffer()); 193 Assert.Throws(typeof(InvalidOperationException), () => context.PayloadAsReadOnlySequence()); 194 } 195 196 [TestCase] ResetContextAndReinitialize()197 public void ResetContextAndReinitialize() 198 { 199 var origBuffer = GetTestBuffer(100); 200 var context = new DefaultDeserializationContext(); 201 context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer)); 202 203 Assert.AreEqual(origBuffer.Length, context.PayloadLength); 204 205 // Reset invalidates context 206 context.Reset(); 207 208 Assert.AreEqual(0, context.PayloadLength); 209 Assert.Throws(typeof(NullReferenceException), () => context.PayloadAsNewBuffer()); 210 Assert.Throws(typeof(NullReferenceException), () => context.PayloadAsReadOnlySequence()); 211 212 // Previously reset context can be initialized again 213 var origBuffer2 = GetTestBuffer(50); 214 context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer2)); 215 216 Assert.AreEqual(origBuffer2.Length, context.PayloadLength); 217 CollectionAssert.AreEqual(origBuffer2, context.PayloadAsNewBuffer()); 218 } 219 GetTestBuffer(int length)220 private byte[] GetTestBuffer(int length) 221 { 222 var testBuffer = new byte[length]; 223 for (int i = 0; i < testBuffer.Length; i++) 224 { 225 testBuffer[i] = (byte) i; 226 } 227 return testBuffer; 228 } 229 } 230 } 231