• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  #region Copyright notice and license
2  
3  // Copyright 2015 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.Diagnostics;
21  using System.Linq;
22  using System.Runtime.InteropServices;
23  using System.Text;
24  using System.Threading;
25  using System.Threading.Tasks;
26  using Grpc.Core;
27  using Grpc.Core.Internal;
28  using Grpc.Core.Utils;
29  using NUnit.Framework;
30  
31  namespace Grpc.Core.Tests
32  {
33      public class MetadataTest
34      {
35          [Test]
AsciiEntry()36          public void AsciiEntry()
37          {
38              var entry = new Metadata.Entry("ABC", "XYZ");
39              Assert.IsFalse(entry.IsBinary);
40              Assert.AreEqual("abc", entry.Key);  // key is in lowercase.
41              Assert.AreEqual("XYZ", entry.Value);
42              CollectionAssert.AreEqual(new[] { (byte)'X', (byte)'Y', (byte)'Z' }, entry.ValueBytes);
43  
44              Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc-bin", "xyz"));
45  
46              Assert.AreEqual("[Entry: key=abc, value=XYZ]", entry.ToString());
47          }
48  
49          [Test]
BinaryEntry()50          public void BinaryEntry()
51          {
52              var bytes = new byte[] { 1, 2, 3 };
53              var entry = new Metadata.Entry("ABC-BIN", bytes);
54              Assert.IsTrue(entry.IsBinary);
55              Assert.AreEqual("abc-bin", entry.Key);  // key is in lowercase.
56              Assert.Throws(typeof(InvalidOperationException), () => { var v = entry.Value; });
57              CollectionAssert.AreEqual(bytes, entry.ValueBytes);
58  
59              Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc", bytes));
60  
61              Assert.AreEqual("[Entry: key=abc-bin, valueBytes=System.Byte[]]", entry.ToString());
62          }
63  
64          [Test]
AsciiEntry_KeyValidity()65          public void AsciiEntry_KeyValidity()
66          {
67              new Metadata.Entry("ABC", "XYZ");
68              new Metadata.Entry("0123456789abc", "XYZ");
69              new Metadata.Entry("-abc", "XYZ");
70              new Metadata.Entry("a_bc_", "XYZ");
71              new Metadata.Entry("abc.xyz", "XYZ");
72              new Metadata.Entry("abc.xyz-bin", new byte[] {1, 2, 3});
73              Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc[", "xyz"));
74              Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc/", "xyz"));
75          }
76  
77          [Test]
KeysAreNormalized_UppercaseKey()78          public void KeysAreNormalized_UppercaseKey()
79          {
80              var uppercaseKey = "ABC";
81              var entry = new Metadata.Entry(uppercaseKey, "XYZ");
82              Assert.AreEqual("abc", entry.Key);
83          }
84  
85          [Test]
KeysAreNormalized_LowercaseKey()86          public void KeysAreNormalized_LowercaseKey()
87          {
88              var lowercaseKey = "abc";
89              var entry = new Metadata.Entry(lowercaseKey, "XYZ");
90              // no allocation if key already lowercase
91              Assert.AreSame(lowercaseKey, entry.Key);
92          }
93  
94          [Test]
Entry_ConstructionPreconditions()95          public void Entry_ConstructionPreconditions()
96          {
97              Assert.Throws(typeof(ArgumentNullException), () => new Metadata.Entry(null, "xyz"));
98              Assert.Throws(typeof(ArgumentNullException), () => new Metadata.Entry("abc", (string)null));
99              Assert.Throws(typeof(ArgumentNullException), () => new Metadata.Entry("abc-bin", (byte[])null));
100          }
101  
102          [Test]
Entry_Immutable()103          public void Entry_Immutable()
104          {
105              var origBytes = new byte[] { 1, 2, 3 };
106              var bytes = new byte[] { 1, 2, 3 };
107              var entry = new Metadata.Entry("ABC-BIN", bytes);
108              bytes[0] = 255;  // changing the array passed to constructor should have any effect.
109              CollectionAssert.AreEqual(origBytes, entry.ValueBytes);
110  
111              entry.ValueBytes[0] = 255;
112              CollectionAssert.AreEqual(origBytes, entry.ValueBytes);
113          }
114  
115          [Test]
Entry_CreateUnsafe_Ascii()116          public unsafe void Entry_CreateUnsafe_Ascii()
117          {
118              var bytes = new byte[] { (byte)'X', (byte)'y' };
119              fixed (byte* ptr = bytes)
120              {
121                  var entry = Metadata.Entry.CreateUnsafe("abc", new IntPtr(ptr), bytes.Length);
122                  Assert.IsFalse(entry.IsBinary);
123                  Assert.AreEqual("abc", entry.Key);
124                  Assert.AreEqual("Xy", entry.Value);
125                  CollectionAssert.AreEqual(bytes, entry.ValueBytes);
126              }
127          }
128  
129          [Test]
Entry_CreateUnsafe_Binary()130          public unsafe void Entry_CreateUnsafe_Binary()
131          {
132              var bytes = new byte[] { 1, 2, 3 };
133              fixed (byte* ptr = bytes)
134              {
135                  var entry = Metadata.Entry.CreateUnsafe("abc-bin", new IntPtr(ptr), bytes.Length);
136                  Assert.IsTrue(entry.IsBinary);
137                  Assert.AreEqual("abc-bin", entry.Key);
138                  Assert.Throws(typeof(InvalidOperationException), () => { var v = entry.Value; });
139                  CollectionAssert.AreEqual(bytes, entry.ValueBytes);
140              }
141          }
142  
143          [Test]
IndexOf()144          public void IndexOf()
145          {
146              var metadata = CreateMetadata();
147              Assert.AreEqual(0, metadata.IndexOf(metadata[0]));
148              Assert.AreEqual(1, metadata.IndexOf(metadata[1]));
149          }
150  
151          [Test]
Insert()152          public void Insert()
153          {
154              var metadata = CreateMetadata();
155              metadata.Insert(0, new Metadata.Entry("new-key", "new-value"));
156              Assert.AreEqual(3, metadata.Count);
157              Assert.AreEqual("new-key", metadata[0].Key);
158              Assert.AreEqual("abc", metadata[1].Key);
159          }
160  
161          [Test]
RemoveAt()162          public void RemoveAt()
163          {
164              var metadata = CreateMetadata();
165              metadata.RemoveAt(0);
166              Assert.AreEqual(1, metadata.Count);
167              Assert.AreEqual("xyz", metadata[0].Key);
168          }
169  
170          [Test]
Remove()171          public void Remove()
172          {
173              var metadata = CreateMetadata();
174              metadata.Remove(metadata[0]);
175              Assert.AreEqual(1, metadata.Count);
176              Assert.AreEqual("xyz", metadata[0].Key);
177          }
178  
179          [Test]
Indexer_Set()180          public void Indexer_Set()
181          {
182              var metadata = CreateMetadata();
183              var entry = new Metadata.Entry("new-key", "new-value");
184  
185              metadata[1] = entry;
186              Assert.AreEqual(entry, metadata[1]);
187          }
188  
189          [Test]
Clear()190          public void Clear()
191          {
192              var metadata = CreateMetadata();
193              metadata.Clear();
194              Assert.AreEqual(0, metadata.Count);
195          }
196  
197          [Test]
Contains()198          public void Contains()
199          {
200              var metadata = CreateMetadata();
201              Assert.IsTrue(metadata.Contains(metadata[0]));
202              Assert.IsFalse(metadata.Contains(new Metadata.Entry("new-key", "new-value")));
203          }
204  
205          [Test]
CopyTo()206          public void CopyTo()
207          {
208              var metadata = CreateMetadata();
209              var array = new Metadata.Entry[metadata.Count + 1];
210  
211              metadata.CopyTo(array, 1);
212              Assert.AreEqual(default(Metadata.Entry), array[0]);
213              Assert.AreEqual(metadata[0], array[1]);
214          }
215  
216          [Test]
IEnumerableGetEnumerator()217          public void IEnumerableGetEnumerator()
218          {
219              var metadata = CreateMetadata();
220              var enumerator = (metadata as System.Collections.IEnumerable).GetEnumerator();
221  
222              int i = 0;
223              while (enumerator.MoveNext())
224              {
225                  Assert.AreEqual(metadata[i], enumerator.Current);
226                  i++;
227              }
228          }
229  
230          [Test]
FreezeMakesReadOnly()231          public void FreezeMakesReadOnly()
232          {
233              var entry = new Metadata.Entry("new-key", "new-value");
234              var metadata = CreateMetadata().Freeze();
235  
236              Assert.IsTrue(metadata.IsReadOnly);
237              Assert.Throws<InvalidOperationException>(() => metadata.Insert(0, entry));
238              Assert.Throws<InvalidOperationException>(() => metadata.RemoveAt(0));
239              Assert.Throws<InvalidOperationException>(() => metadata[0] = entry);
240              Assert.Throws<InvalidOperationException>(() => metadata.Add(entry));
241              Assert.Throws<InvalidOperationException>(() => metadata.Add("new-key", "new-value"));
242              Assert.Throws<InvalidOperationException>(() => metadata.Add("new-key-bin", new byte[] { 0xaa }));
243              Assert.Throws<InvalidOperationException>(() => metadata.Clear());
244              Assert.Throws<InvalidOperationException>(() => metadata.Remove(metadata[0]));
245          }
246  
247          [Test]
GetAll()248          public void GetAll()
249          {
250              var metadata = new Metadata
251              {
252                  { "abc", "abc-value1" },
253                  { "abc", "abc-value2" },
254                  { "xyz", "xyz-value1" },
255              };
256  
257              var abcEntries = metadata.GetAll("abc").ToList();
258              Assert.AreEqual(2, abcEntries.Count);
259              Assert.AreEqual("abc-value1", abcEntries[0].Value);
260              Assert.AreEqual("abc-value2", abcEntries[1].Value);
261  
262              var xyzEntries = metadata.GetAll("xyz").ToList();
263              Assert.AreEqual(1, xyzEntries.Count);
264              Assert.AreEqual("xyz-value1", xyzEntries[0].Value);
265          }
266  
267          [Test]
Get()268          public void Get()
269          {
270              var metadata = new Metadata
271              {
272                  { "abc", "abc-value1" },
273                  { "abc", "abc-value2" },
274                  { "xyz", "xyz-value1" },
275              };
276  
277              var abcEntry = metadata.Get("abc");
278              Assert.AreEqual("abc-value2", abcEntry.Value);
279  
280              var xyzEntry = metadata.Get("xyz");
281              Assert.AreEqual("xyz-value1", xyzEntry.Value);
282  
283              var notFound = metadata.Get("not-found");
284              Assert.AreEqual(null, notFound);
285          }
286  
287          [Test]
GetValue()288          public void GetValue()
289          {
290              var metadata = new Metadata
291              {
292                  { "abc", "abc-value1" },
293                  { "abc", "abc-value2" },
294                  { "xyz", "xyz-value1" },
295                  { "xyz-bin", Encoding.ASCII.GetBytes("xyz-value1") },
296              };
297  
298              var abcValue = metadata.GetValue("abc");
299              Assert.AreEqual("abc-value2", abcValue);
300  
301              var xyzValue = metadata.GetValue("xyz");
302              Assert.AreEqual("xyz-value1", xyzValue);
303  
304              var notFound = metadata.GetValue("not-found");
305              Assert.AreEqual(null, notFound);
306          }
307  
308          [Test]
GetValue_BytesValue()309          public void GetValue_BytesValue()
310          {
311              var metadata = new Metadata
312              {
313                  { "xyz-bin", Encoding.ASCII.GetBytes("xyz-value1") },
314              };
315  
316              Assert.Throws<InvalidOperationException>(() => metadata.GetValue("xyz-bin"));
317          }
318  
319          [Test]
GetValueBytes()320          public void GetValueBytes()
321          {
322              var metadata = new Metadata
323              {
324                  { "abc-bin", Encoding.ASCII.GetBytes("abc-value1") },
325                  { "abc-bin", Encoding.ASCII.GetBytes("abc-value2") },
326                  { "xyz-bin", Encoding.ASCII.GetBytes("xyz-value1") },
327              };
328  
329              var abcValue = metadata.GetValueBytes("abc-bin");
330              Assert.AreEqual(Encoding.ASCII.GetBytes("abc-value2"), abcValue);
331  
332              var xyzValue = metadata.GetValueBytes("xyz-bin");
333              Assert.AreEqual(Encoding.ASCII.GetBytes("xyz-value1"), xyzValue);
334  
335              var notFound = metadata.GetValueBytes("not-found");
336              Assert.AreEqual(null, notFound);
337          }
338  
339          [Test]
GetValueBytes_StringValue()340          public void GetValueBytes_StringValue()
341          {
342              var metadata = new Metadata
343              {
344                  { "xyz", "xyz-value1" },
345              };
346  
347              var xyzValue = metadata.GetValueBytes("xyz");
348              Assert.AreEqual(Encoding.ASCII.GetBytes("xyz-value1"), xyzValue);
349          }
350  
CreateMetadata()351          private Metadata CreateMetadata()
352          {
353              return new Metadata
354              {
355                  { "abc", "abc-value" },
356                  { "xyz", "xyz-value" },
357              };
358          }
359      }
360  }
361