1 #region Copyright notice and license
3 // Copyright 2019 The gRPC Authors
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
20 using System.Collections.Generic;
22 using Grpc.Core.Internal;
23 using Grpc.Core.Utils;
24 using NUnit.Framework;
26 using System.Runtime.InteropServices;
28 #if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY
32 namespace Grpc.Core.Internal.Tests
34 public class DefaultDeserializationContextTest
36 FakeBufferReaderManager fakeBufferReaderManager;
41 fakeBufferReaderManager = new FakeBufferReaderManager();
47 fakeBufferReaderManager.Dispose();
50 #if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY
52 public void PayloadAsReadOnlySequence_ZeroSegmentPayload()
54 var context = new DefaultDeserializationContext();
55 context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List<byte[]> {}));
57 Assert.AreEqual(0, context.PayloadLength);
59 var sequence = context.PayloadAsReadOnlySequence();
61 Assert.AreEqual(ReadOnlySequence<byte>.Empty, sequence);
62 Assert.IsTrue(sequence.IsEmpty);
63 Assert.IsTrue(sequence.IsSingleSegment);
71 public void PayloadAsReadOnlySequence_SingleSegmentPayload(int segmentLength)
73 var origBuffer = GetTestBuffer(segmentLength);
74 var context = new DefaultDeserializationContext();
75 context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer));
77 Assert.AreEqual(origBuffer.Length, context.PayloadLength);
79 var sequence = context.PayloadAsReadOnlySequence();
81 Assert.AreEqual(origBuffer.Length, sequence.Length);
82 Assert.AreEqual(origBuffer.Length, sequence.First.Length);
83 Assert.IsTrue(sequence.IsSingleSegment);
84 CollectionAssert.AreEqual(origBuffer, sequence.First.ToArray());
89 [TestCase(10, 100, 1000)]
90 [TestCase(100, 100, 10)]
91 [TestCase(1000, 1000, 1000)]
92 public void PayloadAsReadOnlySequence_MultiSegmentPayload(int segmentLen1, int segmentLen2, int segmentLen3)
94 var origBuffer1 = GetTestBuffer(segmentLen1);
95 var origBuffer2 = GetTestBuffer(segmentLen2);
96 var origBuffer3 = GetTestBuffer(segmentLen3);
97 int totalLen = origBuffer1.Length + origBuffer2.Length + origBuffer3.Length;
99 var context = new DefaultDeserializationContext();
100 context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List<byte[]> { origBuffer1, origBuffer2, origBuffer3 }));
102 Assert.AreEqual(totalLen, context.PayloadLength);
104 var sequence = context.PayloadAsReadOnlySequence();
106 Assert.AreEqual(totalLen, sequence.Length);
108 var segmentEnumerator = sequence.GetEnumerator();
110 Assert.IsTrue(segmentEnumerator.MoveNext());
111 CollectionAssert.AreEqual(origBuffer1, segmentEnumerator.Current.ToArray());
113 Assert.IsTrue(segmentEnumerator.MoveNext());
114 CollectionAssert.AreEqual(origBuffer2, segmentEnumerator.Current.ToArray());
116 Assert.IsTrue(segmentEnumerator.MoveNext());
117 CollectionAssert.AreEqual(origBuffer3, segmentEnumerator.Current.ToArray());
119 Assert.IsFalse(segmentEnumerator.MoveNext());
124 public void NullPayloadNotAllowed()
126 var context = new DefaultDeserializationContext();
127 Assert.Throws(typeof(InvalidOperationException), () => context.Initialize(fakeBufferReaderManager.CreateNullPayloadBufferReader()));
131 public void PayloadAsNewByteBuffer_ZeroSegmentPayload()
133 var context = new DefaultDeserializationContext();
134 context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List<byte[]> {}));
136 Assert.AreEqual(0, context.PayloadLength);
138 var payload = context.PayloadAsNewBuffer();
139 Assert.AreEqual(0, payload.Length);
147 public void PayloadAsNewByteBuffer_SingleSegmentPayload(int segmentLength)
149 var origBuffer = GetTestBuffer(segmentLength);
150 var context = new DefaultDeserializationContext();
151 context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer));
153 Assert.AreEqual(origBuffer.Length, context.PayloadLength);
155 var payload = context.PayloadAsNewBuffer();
156 CollectionAssert.AreEqual(origBuffer, payload);
161 [TestCase(10, 100, 1000)]
162 [TestCase(100, 100, 10)]
163 [TestCase(1000, 1000, 1000)]
164 public void PayloadAsNewByteBuffer_MultiSegmentPayload(int segmentLen1, int segmentLen2, int segmentLen3)
166 var origBuffer1 = GetTestBuffer(segmentLen1);
167 var origBuffer2 = GetTestBuffer(segmentLen2);
168 var origBuffer3 = GetTestBuffer(segmentLen3);
170 var context = new DefaultDeserializationContext();
171 context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List<byte[]> { origBuffer1, origBuffer2, origBuffer3 }));
173 var payload = context.PayloadAsNewBuffer();
175 var concatenatedOrigBuffers = new List<byte>();
176 concatenatedOrigBuffers.AddRange(origBuffer1);
177 concatenatedOrigBuffers.AddRange(origBuffer2);
178 concatenatedOrigBuffers.AddRange(origBuffer3);
180 Assert.AreEqual(concatenatedOrigBuffers.Count, context.PayloadLength);
181 Assert.AreEqual(concatenatedOrigBuffers.Count, payload.Length);
182 CollectionAssert.AreEqual(concatenatedOrigBuffers, payload);
186 public void GetPayloadMultipleTimesIsIllegal()
188 var origBuffer = GetTestBuffer(100);
189 var context = new DefaultDeserializationContext();
190 context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer));
192 Assert.AreEqual(origBuffer.Length, context.PayloadLength);
194 var payload = context.PayloadAsNewBuffer();
195 CollectionAssert.AreEqual(origBuffer, payload);
197 // Getting payload multiple times is illegal
198 Assert.Throws(typeof(InvalidOperationException), () => context.PayloadAsNewBuffer());
199 #if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY
200 Assert.Throws(typeof(InvalidOperationException), () => context.PayloadAsReadOnlySequence());
205 public void ResetContextAndReinitialize()
207 var origBuffer = GetTestBuffer(100);
208 var context = new DefaultDeserializationContext();
209 context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer));
211 Assert.AreEqual(origBuffer.Length, context.PayloadLength);
213 // Reset invalidates context
216 Assert.AreEqual(0, context.PayloadLength);
217 Assert.Throws(typeof(NullReferenceException), () => context.PayloadAsNewBuffer());
218 #if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY
219 Assert.Throws(typeof(NullReferenceException), () => context.PayloadAsReadOnlySequence());
222 // Previously reset context can be initialized again
223 var origBuffer2 = GetTestBuffer(50);
224 context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer2));
226 Assert.AreEqual(origBuffer2.Length, context.PayloadLength);
227 CollectionAssert.AreEqual(origBuffer2, context.PayloadAsNewBuffer());
230 private byte[] GetTestBuffer(int length)
232 var testBuffer = new byte[length];
233 for (int i = 0; i < testBuffer.Length; i++)
235 testBuffer[i] = (byte) i;