PageRenderTime 37ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/MongoDB.Bson.Tests/IO/BsonChunkPoolTests.cs

http://github.com/mongodb/mongo-csharp-driver
C# | 340 lines | 258 code | 66 blank | 16 comment | 2 complexity | 7ece5e894c571461f604ba1b4bc635bb MD5 | raw file
Possible License(s): Apache-2.0
  1. /* Copyright 2010-present MongoDB Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. using System.Reflection;
  19. using System.Text;
  20. using System.Threading.Tasks;
  21. using FluentAssertions;
  22. using MongoDB.Bson.IO;
  23. using MongoDB.Bson.TestHelpers.XunitExtensions;
  24. using Xunit;
  25. namespace MongoDB.Bson.Tests.IO
  26. {
  27. public class BsonChunkPoolTests
  28. {
  29. [Fact]
  30. public void ChunkSize_get_should_return_expected_result()
  31. {
  32. var subject = new BsonChunkPool(1, 16);
  33. var result = subject.ChunkSize;
  34. result.Should().Be(16);
  35. }
  36. [Fact]
  37. public void constructor_should_initialize_subject()
  38. {
  39. var maxChunkCount = 1;
  40. var chunkSize = 16;
  41. var subject = new BsonChunkPool(maxChunkCount, chunkSize);
  42. var reflector = new Reflector(subject);
  43. subject.MaxChunkCount.Should().Be(maxChunkCount);
  44. subject.ChunkSize.Should().Be(chunkSize);
  45. reflector._disposed.Should().BeFalse();
  46. }
  47. [Theory]
  48. [ParameterAttributeData]
  49. public void constructor_should_throw_chunkSize_is_less_than_zero(
  50. [Values(-1, 0)]
  51. int chunkSize)
  52. {
  53. Action action = () => new BsonChunkPool(1, chunkSize);
  54. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("chunkSize");
  55. }
  56. [Fact]
  57. public void constructor_should_throw_when_MaxChunkCount_is_less_than_zero()
  58. {
  59. Action action = () => new BsonChunkPool(-1, 16);
  60. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("maxChunkCount");
  61. }
  62. [Fact]
  63. public void Default_get_should_return_expected_result()
  64. {
  65. var result = BsonChunkPool.Default;
  66. result.ChunkSize.Should().Be(64 * 1024);
  67. result.MaxChunkCount.Should().Be(8192);
  68. }
  69. [Fact]
  70. public void Default_set_should_have_expected_effect()
  71. {
  72. var originalDefaultPool = BsonChunkPool.Default;
  73. try
  74. {
  75. var newDefaultPool = new BsonChunkPool(1, 16);
  76. BsonChunkPool.Default = newDefaultPool;
  77. BsonChunkPool.Default.Should().BeSameAs(newDefaultPool);
  78. }
  79. finally
  80. {
  81. BsonChunkPool.Default = originalDefaultPool;
  82. }
  83. }
  84. [Fact]
  85. public void Default_set_should_throw_when_value_is_null()
  86. {
  87. Action action = () => BsonChunkPool.Default = null;
  88. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("value");
  89. }
  90. [Fact]
  91. public void Dispose_can_be_called_more_than_once()
  92. {
  93. var subject = new BsonChunkPool(1, 16);
  94. subject.Dispose();
  95. subject.Dispose();
  96. }
  97. [Fact]
  98. public void Dispose_should_dispose_subject()
  99. {
  100. var subject = new BsonChunkPool(1, 16);
  101. subject.Dispose();
  102. var reflector = new Reflector(subject);
  103. reflector._disposed.Should().BeTrue();
  104. }
  105. [Theory]
  106. [ParameterAttributeData]
  107. public void GetChunk_should_return_expected_result(
  108. [Values(1, 15, 16, 17, 32)]
  109. int requestedSize)
  110. {
  111. var subject = new BsonChunkPool(1, 16);
  112. var result = subject.GetChunk(requestedSize);
  113. result.Bytes.Count.Should().Be(16);
  114. }
  115. [Fact]
  116. public void GetChunk_should_return_pooled_chunk_when_one_is_availabe()
  117. {
  118. var subject = new BsonChunkPool(1, 16);
  119. var pooledChunk = subject.GetChunk(1);
  120. var expectedArray = pooledChunk.Bytes.Array;
  121. var expectedOffset = pooledChunk.Bytes.Offset;
  122. pooledChunk.Dispose();
  123. var result = subject.GetChunk(1);
  124. result.Bytes.Array.Should().BeSameAs(expectedArray);
  125. result.Bytes.Offset.Should().Be(expectedOffset);
  126. result.Bytes.Count.Should().Be(16);
  127. }
  128. [Fact]
  129. public void GetChunk_should_throw_when_subject_is_disposed()
  130. {
  131. var subject = new BsonChunkPool(1, 16);
  132. subject.Dispose();
  133. Action action = () => subject.GetChunk(1);
  134. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("BsonChunkPool");
  135. }
  136. [Fact]
  137. public void MaxChunkCount_get_should_return_expected_result()
  138. {
  139. var subject = new BsonChunkPool(1, 16);
  140. var result = subject.MaxChunkCount;
  141. result.Should().Be(1);
  142. }
  143. // nested types
  144. private class Reflector
  145. {
  146. private readonly BsonChunkPool _instance;
  147. public Reflector(BsonChunkPool instance)
  148. {
  149. _instance = instance;
  150. }
  151. public bool _disposed
  152. {
  153. get
  154. {
  155. var field = typeof(BsonChunkPool).GetField("_disposed", BindingFlags.NonPublic | BindingFlags.Instance);
  156. return (bool)field.GetValue(_instance);
  157. }
  158. }
  159. }
  160. }
  161. public class BsonChunkPool_DisposableChunkTests
  162. {
  163. [Fact]
  164. public void Bytes_get_should_return_expected_result()
  165. {
  166. var pool = new BsonChunkPool(1, 16);
  167. var subject = pool.GetChunk(1);
  168. var result = subject.Bytes;
  169. result.Array.Length.Should().Be(16);
  170. result.Offset.Should().Be(0);
  171. result.Count.Should().Be(16);
  172. }
  173. [Fact]
  174. public void Bytes_get_should_throw_when_subject_is_disposed()
  175. {
  176. var pool = new BsonChunkPool(1, 16);
  177. var subject = pool.GetChunk(1);
  178. subject.Dispose();
  179. Action action = () => { var _ = subject.Bytes; };
  180. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("DisposableChunk");
  181. }
  182. [Fact]
  183. public void Dispose_can_be_called_more_than_once()
  184. {
  185. var pool = new BsonChunkPool(1, 16);
  186. var subject = pool.GetChunk(1);
  187. subject.Dispose();
  188. subject.Dispose();
  189. }
  190. [Fact]
  191. public void Dispose_should_dispose_subject()
  192. {
  193. var pool = new BsonChunkPool(1, 16);
  194. var subject = pool.GetChunk(1);
  195. subject.Dispose();
  196. var reflector = new Reflector(subject);
  197. reflector._disposed.Should().BeTrue();
  198. }
  199. [Fact]
  200. public void Dispose_should_return_chunk_to_the_pool()
  201. {
  202. var pool = new BsonChunkPool(1, 16);
  203. var subject = pool.GetChunk(1);
  204. subject.Dispose();
  205. pool.ChunkCount.Should().Be(1);
  206. }
  207. [Theory]
  208. [ParameterAttributeData]
  209. public void Dispose_should_return_chunk_to_the_pool_after_all_handles_have_been_disposed(
  210. [Values(0, 1, 2, 3, 4, 16)]
  211. int numberOfHandles,
  212. [Values(false, true)]
  213. bool disposeSubjectLast)
  214. {
  215. var pool = new BsonChunkPool(1, 16);
  216. var subject = pool.GetChunk(1);
  217. var handles = new List<IBsonChunk>();
  218. for (var n = 0; n < numberOfHandles; n++)
  219. {
  220. handles.Add(subject.Fork());
  221. }
  222. if (disposeSubjectLast)
  223. {
  224. handles.Add(subject);
  225. }
  226. else
  227. {
  228. handles.Insert(0, subject);
  229. }
  230. foreach (var handle in handles)
  231. {
  232. pool.ChunkCount.Should().Be(0);
  233. handle.Dispose();
  234. }
  235. pool.ChunkCount.Should().Be(1);
  236. }
  237. [Fact]
  238. public void Fork_should_return_expected_result()
  239. {
  240. var pool = new BsonChunkPool(1, 16);
  241. var subject = pool.GetChunk(1);
  242. var handle = subject.Fork();
  243. handle.Bytes.Array.Should().BeSameAs(subject.Bytes.Array);
  244. handle.Bytes.Offset.Should().Be(subject.Bytes.Offset);
  245. handle.Bytes.Count.Should().Be(subject.Bytes.Count);
  246. }
  247. [Fact]
  248. public void Fork_should_throw_when_subject_is_disposed()
  249. {
  250. var pool = new BsonChunkPool(1, 16);
  251. var subject = pool.GetChunk(1);
  252. subject.Dispose();
  253. Action action = () => subject.Fork();
  254. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("DisposableChunk");
  255. }
  256. // nested types
  257. private class Reflector
  258. {
  259. private readonly IBsonChunk _instance;
  260. public Reflector(IBsonChunk instance)
  261. {
  262. _instance = instance;
  263. }
  264. public bool _disposed
  265. {
  266. get
  267. {
  268. var field = _instance.GetType().GetField("_disposed", BindingFlags.NonPublic | BindingFlags.Instance);
  269. return (bool)field.GetValue(_instance);
  270. }
  271. }
  272. }
  273. }
  274. }