MetadataTest.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #region Copyright notice and license
  2. // Copyright 2015 gRPC authors.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. #endregion
  16. using System;
  17. using System.Diagnostics;
  18. using System.Runtime.InteropServices;
  19. using System.Threading;
  20. using System.Threading.Tasks;
  21. using Grpc.Core;
  22. using Grpc.Core.Internal;
  23. using Grpc.Core.Utils;
  24. using NUnit.Framework;
  25. namespace Grpc.Core.Tests
  26. {
  27. public class MetadataTest
  28. {
  29. [Test]
  30. public void AsciiEntry()
  31. {
  32. var entry = new Metadata.Entry("ABC", "XYZ");
  33. Assert.IsFalse(entry.IsBinary);
  34. Assert.AreEqual("abc", entry.Key); // key is in lowercase.
  35. Assert.AreEqual("XYZ", entry.Value);
  36. CollectionAssert.AreEqual(new[] { (byte)'X', (byte)'Y', (byte)'Z' }, entry.ValueBytes);
  37. Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc-bin", "xyz"));
  38. Assert.AreEqual("[Entry: key=abc, value=XYZ]", entry.ToString());
  39. }
  40. [Test]
  41. public void BinaryEntry()
  42. {
  43. var bytes = new byte[] { 1, 2, 3 };
  44. var entry = new Metadata.Entry("ABC-BIN", bytes);
  45. Assert.IsTrue(entry.IsBinary);
  46. Assert.AreEqual("abc-bin", entry.Key); // key is in lowercase.
  47. Assert.Throws(typeof(InvalidOperationException), () => { var v = entry.Value; });
  48. CollectionAssert.AreEqual(bytes, entry.ValueBytes);
  49. Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc", bytes));
  50. Assert.AreEqual("[Entry: key=abc-bin, valueBytes=System.Byte[]]", entry.ToString());
  51. }
  52. [Test]
  53. public void AsciiEntry_KeyValidity()
  54. {
  55. new Metadata.Entry("ABC", "XYZ");
  56. new Metadata.Entry("0123456789abc", "XYZ");
  57. new Metadata.Entry("-abc", "XYZ");
  58. new Metadata.Entry("a_bc_", "XYZ");
  59. new Metadata.Entry("abc.xyz", "XYZ");
  60. new Metadata.Entry("abc.xyz-bin", new byte[] {1, 2, 3});
  61. Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc[", "xyz"));
  62. Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc/", "xyz"));
  63. }
  64. [Test]
  65. public void KeysAreNormalized_UppercaseKey()
  66. {
  67. var uppercaseKey = "ABC";
  68. var entry = new Metadata.Entry(uppercaseKey, "XYZ");
  69. Assert.AreEqual("abc", entry.Key);
  70. }
  71. [Test]
  72. public void KeysAreNormalized_LowercaseKey()
  73. {
  74. var lowercaseKey = "abc";
  75. var entry = new Metadata.Entry(lowercaseKey, "XYZ");
  76. // no allocation if key already lowercase
  77. Assert.AreSame(lowercaseKey, entry.Key);
  78. }
  79. [Test]
  80. public void Entry_ConstructionPreconditions()
  81. {
  82. Assert.Throws(typeof(ArgumentNullException), () => new Metadata.Entry(null, "xyz"));
  83. Assert.Throws(typeof(ArgumentNullException), () => new Metadata.Entry("abc", (string)null));
  84. Assert.Throws(typeof(ArgumentNullException), () => new Metadata.Entry("abc-bin", (byte[])null));
  85. }
  86. [Test]
  87. public void Entry_Immutable()
  88. {
  89. var origBytes = new byte[] { 1, 2, 3 };
  90. var bytes = new byte[] { 1, 2, 3 };
  91. var entry = new Metadata.Entry("ABC-BIN", bytes);
  92. bytes[0] = 255; // changing the array passed to constructor should have any effect.
  93. CollectionAssert.AreEqual(origBytes, entry.ValueBytes);
  94. entry.ValueBytes[0] = 255;
  95. CollectionAssert.AreEqual(origBytes, entry.ValueBytes);
  96. }
  97. [Test]
  98. public unsafe void Entry_CreateUnsafe_Ascii()
  99. {
  100. var bytes = new byte[] { (byte)'X', (byte)'y' };
  101. fixed (byte* ptr = bytes)
  102. {
  103. var entry = Metadata.Entry.CreateUnsafe("abc", new IntPtr(ptr), bytes.Length);
  104. Assert.IsFalse(entry.IsBinary);
  105. Assert.AreEqual("abc", entry.Key);
  106. Assert.AreEqual("Xy", entry.Value);
  107. CollectionAssert.AreEqual(bytes, entry.ValueBytes);
  108. }
  109. }
  110. [Test]
  111. public unsafe void Entry_CreateUnsafe_Binary()
  112. {
  113. var bytes = new byte[] { 1, 2, 3 };
  114. fixed (byte* ptr = bytes)
  115. {
  116. var entry = Metadata.Entry.CreateUnsafe("abc-bin", new IntPtr(ptr), bytes.Length);
  117. Assert.IsTrue(entry.IsBinary);
  118. Assert.AreEqual("abc-bin", entry.Key);
  119. Assert.Throws(typeof(InvalidOperationException), () => { var v = entry.Value; });
  120. CollectionAssert.AreEqual(bytes, entry.ValueBytes);
  121. }
  122. }
  123. [Test]
  124. public void IndexOf()
  125. {
  126. var metadata = CreateMetadata();
  127. Assert.AreEqual(0, metadata.IndexOf(metadata[0]));
  128. Assert.AreEqual(1, metadata.IndexOf(metadata[1]));
  129. }
  130. [Test]
  131. public void Insert()
  132. {
  133. var metadata = CreateMetadata();
  134. metadata.Insert(0, new Metadata.Entry("new-key", "new-value"));
  135. Assert.AreEqual(3, metadata.Count);
  136. Assert.AreEqual("new-key", metadata[0].Key);
  137. Assert.AreEqual("abc", metadata[1].Key);
  138. }
  139. [Test]
  140. public void RemoveAt()
  141. {
  142. var metadata = CreateMetadata();
  143. metadata.RemoveAt(0);
  144. Assert.AreEqual(1, metadata.Count);
  145. Assert.AreEqual("xyz", metadata[0].Key);
  146. }
  147. [Test]
  148. public void Remove()
  149. {
  150. var metadata = CreateMetadata();
  151. metadata.Remove(metadata[0]);
  152. Assert.AreEqual(1, metadata.Count);
  153. Assert.AreEqual("xyz", metadata[0].Key);
  154. }
  155. [Test]
  156. public void Indexer_Set()
  157. {
  158. var metadata = CreateMetadata();
  159. var entry = new Metadata.Entry("new-key", "new-value");
  160. metadata[1] = entry;
  161. Assert.AreEqual(entry, metadata[1]);
  162. }
  163. [Test]
  164. public void Clear()
  165. {
  166. var metadata = CreateMetadata();
  167. metadata.Clear();
  168. Assert.AreEqual(0, metadata.Count);
  169. }
  170. [Test]
  171. public void Contains()
  172. {
  173. var metadata = CreateMetadata();
  174. Assert.IsTrue(metadata.Contains(metadata[0]));
  175. Assert.IsFalse(metadata.Contains(new Metadata.Entry("new-key", "new-value")));
  176. }
  177. [Test]
  178. public void CopyTo()
  179. {
  180. var metadata = CreateMetadata();
  181. var array = new Metadata.Entry[metadata.Count + 1];
  182. metadata.CopyTo(array, 1);
  183. Assert.AreEqual(default(Metadata.Entry), array[0]);
  184. Assert.AreEqual(metadata[0], array[1]);
  185. }
  186. [Test]
  187. public void IEnumerableGetEnumerator()
  188. {
  189. var metadata = CreateMetadata();
  190. var enumerator = (metadata as System.Collections.IEnumerable).GetEnumerator();
  191. int i = 0;
  192. while (enumerator.MoveNext())
  193. {
  194. Assert.AreEqual(metadata[i], enumerator.Current);
  195. i++;
  196. }
  197. }
  198. [Test]
  199. public void FreezeMakesReadOnly()
  200. {
  201. var entry = new Metadata.Entry("new-key", "new-value");
  202. var metadata = CreateMetadata().Freeze();
  203. Assert.IsTrue(metadata.IsReadOnly);
  204. Assert.Throws<InvalidOperationException>(() => metadata.Insert(0, entry));
  205. Assert.Throws<InvalidOperationException>(() => metadata.RemoveAt(0));
  206. Assert.Throws<InvalidOperationException>(() => metadata[0] = entry);
  207. Assert.Throws<InvalidOperationException>(() => metadata.Add(entry));
  208. Assert.Throws<InvalidOperationException>(() => metadata.Add("new-key", "new-value"));
  209. Assert.Throws<InvalidOperationException>(() => metadata.Add("new-key-bin", new byte[] { 0xaa }));
  210. Assert.Throws<InvalidOperationException>(() => metadata.Clear());
  211. Assert.Throws<InvalidOperationException>(() => metadata.Remove(metadata[0]));
  212. }
  213. private Metadata CreateMetadata()
  214. {
  215. return new Metadata
  216. {
  217. { "abc", "abc-value" },
  218. { "xyz", "xyz-value" },
  219. };
  220. }
  221. }
  222. }