• 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