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.Runtime.InteropServices; 22 using System.Threading; 23 using System.Threading.Tasks; 24 using Grpc.Core; 25 using Grpc.Core.Internal; 26 using Grpc.Core.Utils; 27 using NUnit.Framework; 28 29 namespace Grpc.Core.Tests 30 { 31 public class MetadataTest 32 { 33 [Test] AsciiEntry()34 public void AsciiEntry() 35 { 36 var entry = new Metadata.Entry("ABC", "XYZ"); 37 Assert.IsFalse(entry.IsBinary); 38 Assert.AreEqual("abc", entry.Key); // key is in lowercase. 39 Assert.AreEqual("XYZ", entry.Value); 40 CollectionAssert.AreEqual(new[] { (byte)'X', (byte)'Y', (byte)'Z' }, entry.ValueBytes); 41 42 Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc-bin", "xyz")); 43 44 Assert.AreEqual("[Entry: key=abc, value=XYZ]", entry.ToString()); 45 } 46 47 [Test] BinaryEntry()48 public void BinaryEntry() 49 { 50 var bytes = new byte[] { 1, 2, 3 }; 51 var entry = new Metadata.Entry("ABC-BIN", bytes); 52 Assert.IsTrue(entry.IsBinary); 53 Assert.AreEqual("abc-bin", entry.Key); // key is in lowercase. 54 Assert.Throws(typeof(InvalidOperationException), () => { var v = entry.Value; }); 55 CollectionAssert.AreEqual(bytes, entry.ValueBytes); 56 57 Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc", bytes)); 58 59 Assert.AreEqual("[Entry: key=abc-bin, valueBytes=System.Byte[]]", entry.ToString()); 60 } 61 62 [Test] AsciiEntry_KeyValidity()63 public void AsciiEntry_KeyValidity() 64 { 65 new Metadata.Entry("ABC", "XYZ"); 66 new Metadata.Entry("0123456789abc", "XYZ"); 67 new Metadata.Entry("-abc", "XYZ"); 68 new Metadata.Entry("a_bc_", "XYZ"); 69 new Metadata.Entry("abc.xyz", "XYZ"); 70 new Metadata.Entry("abc.xyz-bin", new byte[] {1, 2, 3}); 71 Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc[", "xyz")); 72 Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc/", "xyz")); 73 } 74 75 [Test] Entry_ConstructionPreconditions()76 public void Entry_ConstructionPreconditions() 77 { 78 Assert.Throws(typeof(ArgumentNullException), () => new Metadata.Entry(null, "xyz")); 79 Assert.Throws(typeof(ArgumentNullException), () => new Metadata.Entry("abc", (string)null)); 80 Assert.Throws(typeof(ArgumentNullException), () => new Metadata.Entry("abc-bin", (byte[])null)); 81 } 82 83 [Test] Entry_Immutable()84 public void Entry_Immutable() 85 { 86 var origBytes = new byte[] { 1, 2, 3 }; 87 var bytes = new byte[] { 1, 2, 3 }; 88 var entry = new Metadata.Entry("ABC-BIN", bytes); 89 bytes[0] = 255; // changing the array passed to constructor should have any effect. 90 CollectionAssert.AreEqual(origBytes, entry.ValueBytes); 91 92 entry.ValueBytes[0] = 255; 93 CollectionAssert.AreEqual(origBytes, entry.ValueBytes); 94 } 95 96 [Test] Entry_CreateUnsafe_Ascii()97 public void Entry_CreateUnsafe_Ascii() 98 { 99 var bytes = new byte[] { (byte)'X', (byte)'y' }; 100 var entry = Metadata.Entry.CreateUnsafe("abc", bytes); 101 Assert.IsFalse(entry.IsBinary); 102 Assert.AreEqual("abc", entry.Key); 103 Assert.AreEqual("Xy", entry.Value); 104 CollectionAssert.AreEqual(bytes, entry.ValueBytes); 105 } 106 107 [Test] Entry_CreateUnsafe_Binary()108 public void Entry_CreateUnsafe_Binary() 109 { 110 var bytes = new byte[] { 1, 2, 3 }; 111 var entry = Metadata.Entry.CreateUnsafe("abc-bin", bytes); 112 Assert.IsTrue(entry.IsBinary); 113 Assert.AreEqual("abc-bin", entry.Key); 114 Assert.Throws(typeof(InvalidOperationException), () => { var v = entry.Value; }); 115 CollectionAssert.AreEqual(bytes, entry.ValueBytes); 116 } 117 118 [Test] IndexOf()119 public void IndexOf() 120 { 121 var metadata = CreateMetadata(); 122 Assert.AreEqual(0, metadata.IndexOf(metadata[0])); 123 Assert.AreEqual(1, metadata.IndexOf(metadata[1])); 124 } 125 126 [Test] Insert()127 public void Insert() 128 { 129 var metadata = CreateMetadata(); 130 metadata.Insert(0, new Metadata.Entry("new-key", "new-value")); 131 Assert.AreEqual(3, metadata.Count); 132 Assert.AreEqual("new-key", metadata[0].Key); 133 Assert.AreEqual("abc", metadata[1].Key); 134 } 135 136 [Test] RemoveAt()137 public void RemoveAt() 138 { 139 var metadata = CreateMetadata(); 140 metadata.RemoveAt(0); 141 Assert.AreEqual(1, metadata.Count); 142 Assert.AreEqual("xyz", metadata[0].Key); 143 } 144 145 [Test] Remove()146 public void Remove() 147 { 148 var metadata = CreateMetadata(); 149 metadata.Remove(metadata[0]); 150 Assert.AreEqual(1, metadata.Count); 151 Assert.AreEqual("xyz", metadata[0].Key); 152 } 153 154 [Test] Indexer_Set()155 public void Indexer_Set() 156 { 157 var metadata = CreateMetadata(); 158 var entry = new Metadata.Entry("new-key", "new-value"); 159 160 metadata[1] = entry; 161 Assert.AreEqual(entry, metadata[1]); 162 } 163 164 [Test] Clear()165 public void Clear() 166 { 167 var metadata = CreateMetadata(); 168 metadata.Clear(); 169 Assert.AreEqual(0, metadata.Count); 170 } 171 172 [Test] Contains()173 public void Contains() 174 { 175 var metadata = CreateMetadata(); 176 Assert.IsTrue(metadata.Contains(metadata[0])); 177 Assert.IsFalse(metadata.Contains(new Metadata.Entry("new-key", "new-value"))); 178 } 179 180 [Test] CopyTo()181 public void CopyTo() 182 { 183 var metadata = CreateMetadata(); 184 var array = new Metadata.Entry[metadata.Count + 1]; 185 186 metadata.CopyTo(array, 1); 187 Assert.AreEqual(default(Metadata.Entry), array[0]); 188 Assert.AreEqual(metadata[0], array[1]); 189 } 190 191 [Test] IEnumerableGetEnumerator()192 public void IEnumerableGetEnumerator() 193 { 194 var metadata = CreateMetadata(); 195 var enumerator = (metadata as System.Collections.IEnumerable).GetEnumerator(); 196 197 int i = 0; 198 while (enumerator.MoveNext()) 199 { 200 Assert.AreEqual(metadata[i], enumerator.Current); 201 i++; 202 } 203 } 204 205 [Test] FreezeMakesReadOnly()206 public void FreezeMakesReadOnly() 207 { 208 var entry = new Metadata.Entry("new-key", "new-value"); 209 var metadata = CreateMetadata().Freeze(); 210 211 Assert.IsTrue(metadata.IsReadOnly); 212 Assert.Throws<InvalidOperationException>(() => metadata.Insert(0, entry)); 213 Assert.Throws<InvalidOperationException>(() => metadata.RemoveAt(0)); 214 Assert.Throws<InvalidOperationException>(() => metadata[0] = entry); 215 Assert.Throws<InvalidOperationException>(() => metadata.Add(entry)); 216 Assert.Throws<InvalidOperationException>(() => metadata.Add("new-key", "new-value")); 217 Assert.Throws<InvalidOperationException>(() => metadata.Add("new-key-bin", new byte[] { 0xaa })); 218 Assert.Throws<InvalidOperationException>(() => metadata.Clear()); 219 Assert.Throws<InvalidOperationException>(() => metadata.Remove(metadata[0])); 220 } 221 CreateMetadata()222 private Metadata CreateMetadata() 223 { 224 return new Metadata 225 { 226 { "abc", "abc-value" }, 227 { "xyz", "xyz-value" }, 228 }; 229 } 230 } 231 } 232