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