PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

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

http://github.com/mongodb/mongo-csharp-driver
C# | 346 lines | 266 code | 65 blank | 15 comment | 4 complexity | 9f91c359c6b9ca0506ff6840223363b0 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 Moq;
  25. using Xunit;
  26. namespace MongoDB.Bson.Tests.IO
  27. {
  28. public class OutputBufferChunkSourceTests
  29. {
  30. [Fact]
  31. public void BaseSource_get_should_return_expected_result()
  32. {
  33. var mockBaseSource = new Mock<IBsonChunkSource>();
  34. var subject = new OutputBufferChunkSource(mockBaseSource.Object);
  35. var result = subject.BaseSource;
  36. result.Should().BeSameAs(mockBaseSource.Object);
  37. }
  38. [Fact]
  39. public void BaseSource_get_should_throw_when_subject_is_disposed()
  40. {
  41. var mockBaseSource = new Mock<IBsonChunkSource>();
  42. var subject = new OutputBufferChunkSource(mockBaseSource.Object);
  43. subject.Dispose();
  44. Action action = () => { var _ = subject.BaseSource; };
  45. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("OutputBufferChunkSource");
  46. }
  47. [Fact]
  48. public void constructor_should_initialize_subject()
  49. {
  50. var mockBaseSource = new Mock<IBsonChunkSource>();
  51. var initialUnpooledChunkSize = 2;
  52. var minChunkSize = 4;
  53. var maxChunkSize = 8;
  54. var subject = new OutputBufferChunkSource(mockBaseSource.Object, initialUnpooledChunkSize, minChunkSize, maxChunkSize);
  55. var reflector = new Reflector(subject);
  56. subject.BaseSource.Should().BeSameAs(mockBaseSource.Object);
  57. subject.InitialUnpooledChunkSize.Should().Be(initialUnpooledChunkSize);
  58. subject.MaxChunkSize.Should().Be(maxChunkSize);
  59. subject.MinChunkSize.Should().Be(minChunkSize);
  60. reflector._disposed.Should().BeFalse();
  61. }
  62. [Fact]
  63. public void constructor_should_throw_when_baseSource_is_null()
  64. {
  65. Action action = () => new OutputBufferChunkSource(null);
  66. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("baseSource");
  67. }
  68. [Fact]
  69. public void constructor_should_throw_when_initialUnpooledChunkSize_is_less_than_zero()
  70. {
  71. var mockBaseSource = new Mock<IBsonChunkSource>();
  72. Action action = () => new OutputBufferChunkSource(mockBaseSource.Object, initialUnpooledChunkSize: -1);
  73. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("initialUnpooledChunkSize");
  74. }
  75. [Theory]
  76. [ParameterAttributeData]
  77. public void constructor_should_throw_when_maxChunkSize_is_less_than_or_equal_to_zero(
  78. [Values(-1, 0)]
  79. int maxChunkSize)
  80. {
  81. var mockBaseSource = new Mock<IBsonChunkSource>();
  82. Action action = () => new OutputBufferChunkSource(mockBaseSource.Object, maxChunkSize: -1);
  83. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("maxChunkSize");
  84. }
  85. [Fact]
  86. public void constructor_should_throw_when_maxChunkSize_is_less_than_minChunkSize()
  87. {
  88. var mockBaseSource = new Mock<IBsonChunkSource>();
  89. Action action = () => new OutputBufferChunkSource(mockBaseSource.Object, minChunkSize: 8, maxChunkSize: 4);
  90. action.ShouldThrow<ArgumentException>().And.ParamName.Should().Be("maxChunkSize");
  91. }
  92. [Theory]
  93. [ParameterAttributeData]
  94. public void constructor_should_throw_when_maxChunkSize_is_not_a_power_of_2(
  95. [Values(3, 5, 7, 9, 15, 17)]
  96. int maxChunkSize)
  97. {
  98. var mockBaseSource = new Mock<IBsonChunkSource>();
  99. Action action = () => new OutputBufferChunkSource(mockBaseSource.Object, maxChunkSize: -1);
  100. action.ShouldThrow<ArgumentException>().And.ParamName.Should().Be("maxChunkSize");
  101. }
  102. [Theory]
  103. [ParameterAttributeData]
  104. public void constructor_should_throw_when_minChunkSize_is_less_than_or_equal_to_zero(
  105. [Values(-1, 0)]
  106. int minChunkSize)
  107. {
  108. var mockBaseSource = new Mock<IBsonChunkSource>();
  109. Action action = () => new OutputBufferChunkSource(mockBaseSource.Object, minChunkSize: -1);
  110. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("minChunkSize");
  111. }
  112. [Theory]
  113. [ParameterAttributeData]
  114. public void constructor_should_throw_when_minChunkSize_is_not_a_power_of_2(
  115. [Values(3, 5, 7, 9, 15, 17)]
  116. int minChunkSize)
  117. {
  118. var mockBaseSource = new Mock<IBsonChunkSource>();
  119. Action action = () => new OutputBufferChunkSource(mockBaseSource.Object, minChunkSize: -1);
  120. action.ShouldThrow<ArgumentException>().And.ParamName.Should().Be("minChunkSize");
  121. }
  122. [Fact]
  123. public void Dispose_can_be_called_more_than_once()
  124. {
  125. var mockBaseSource = new Mock<IBsonChunkSource>();
  126. var subject = new OutputBufferChunkSource(mockBaseSource.Object);
  127. subject.Dispose();
  128. subject.Dispose();
  129. }
  130. [Fact]
  131. public void Dispose_should_dispose_subject()
  132. {
  133. var mockBaseSource = new Mock<IBsonChunkSource>();
  134. var subject = new OutputBufferChunkSource(mockBaseSource.Object);
  135. subject.Dispose();
  136. var reflector = new Reflector(subject);
  137. reflector._disposed.Should().BeTrue();
  138. }
  139. [Theory]
  140. [InlineData(1, new int[] { })]
  141. [InlineData(2, new int[] { 4 })]
  142. [InlineData(3, new int[] { 4, 8 })]
  143. [InlineData(4, new int[] { 4, 8, 16 })]
  144. [InlineData(5, new int[] { 4, 8, 16, 32 })]
  145. [InlineData(6, new int[] { 4, 8, 16, 32, 32 })]
  146. [InlineData(7, new int[] { 4, 8, 16, 32, 32, 32 })]
  147. public void GetChunk_should_return_expected_result_when_initialUnpooledChunkSize_is_not_zero(int numberOfCalls, int[] expectedRequestSizes)
  148. {
  149. var mockBaseSource = new Mock<IBsonChunkSource>();
  150. mockBaseSource.Setup(s => s.GetChunk(It.IsAny<int>())).Returns((int requestedSize) => new ByteArrayChunk(requestedSize));
  151. var subject = new OutputBufferChunkSource(mockBaseSource.Object, initialUnpooledChunkSize: 2, minChunkSize: 4, maxChunkSize: 32);
  152. var result = subject.GetChunk(1);
  153. result.Bytes.Count.Should().Be(2);
  154. for (var n = 0; n < numberOfCalls - 1; n++)
  155. {
  156. result = subject.GetChunk(1);
  157. result.Bytes.Count.Should().Be(expectedRequestSizes[n]);
  158. }
  159. mockBaseSource.Verify(s => s.GetChunk(It.IsAny<int>()), Times.Exactly(numberOfCalls - 1));
  160. foreach (var expectedRequestSize in expectedRequestSizes)
  161. {
  162. var requiredNumberOfCalls = expectedRequestSizes.Count(s => s == expectedRequestSize);
  163. mockBaseSource.Verify(s => s.GetChunk(expectedRequestSize), Times.Exactly(requiredNumberOfCalls));
  164. }
  165. }
  166. [Theory]
  167. [InlineData(1, new int[] { 4 })]
  168. [InlineData(2, new int[] { 4, 8 })]
  169. [InlineData(3, new int[] { 4, 8, 16 })]
  170. [InlineData(4, new int[] { 4, 8, 16, 32 })]
  171. [InlineData(5, new int[] { 4, 8, 16, 32, 32 })]
  172. [InlineData(6, new int[] { 4, 8, 16, 32, 32, 32 })]
  173. public void GetChunk_should_return_expected_result_when_initialUnpooledChunkSize_is_zero(int numberOfCalls, int[] expectedRequestSizes)
  174. {
  175. var mockBaseSource = new Mock<IBsonChunkSource>();
  176. mockBaseSource.Setup(s => s.GetChunk(It.IsAny<int>())).Returns((int requestedSize) => new ByteArrayChunk(requestedSize));
  177. var subject = new OutputBufferChunkSource(mockBaseSource.Object, initialUnpooledChunkSize: 0, minChunkSize: 4, maxChunkSize: 32);
  178. for (var n = 0; n < numberOfCalls; n++)
  179. {
  180. var result = subject.GetChunk(1);
  181. result.Bytes.Count.Should().Be(expectedRequestSizes[n]);
  182. }
  183. mockBaseSource.Verify(s => s.GetChunk(It.IsAny<int>()), Times.Exactly(numberOfCalls));
  184. foreach (var expectedRequestSize in expectedRequestSizes)
  185. {
  186. var requiredNumberOfCalls = expectedRequestSizes.Count(s => s == expectedRequestSize);
  187. mockBaseSource.Verify(s => s.GetChunk(expectedRequestSize), Times.Exactly(requiredNumberOfCalls));
  188. }
  189. }
  190. [Theory]
  191. [ParameterAttributeData]
  192. public void GetChunk_should_throw_when_requestedSize_is_less_than_or_equal_to_zero(
  193. [Values(-1, 0)]
  194. int requestedSize)
  195. {
  196. var mockBaseSource = new Mock<IBsonChunkSource>();
  197. var subject = new OutputBufferChunkSource(mockBaseSource.Object);
  198. Action action = () => subject.GetChunk(requestedSize);
  199. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("requestedSize");
  200. }
  201. [Fact]
  202. public void GetChunk_should_throw_when_subject_is_disposed()
  203. {
  204. var mockBaseSource = new Mock<IBsonChunkSource>();
  205. var subject = new OutputBufferChunkSource(mockBaseSource.Object);
  206. subject.Dispose();
  207. Action action = () => subject.GetChunk(1);
  208. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("OutputBufferChunkSource");
  209. }
  210. [Fact]
  211. public void InitialUnpooledChunkSize_get_should_return_expected_result()
  212. {
  213. var mockBaseSource = new Mock<IBsonChunkSource>();
  214. var initialUnpooledChunkSize = Reflector.DefaultInitialUnpooledChunkSize * 2;
  215. var subject = new OutputBufferChunkSource(mockBaseSource.Object, initialUnpooledChunkSize: initialUnpooledChunkSize);
  216. var result = subject.InitialUnpooledChunkSize;
  217. result.Should().Be(initialUnpooledChunkSize);
  218. }
  219. [Fact]
  220. public void MaxChunkSize_get_should_return_expected_result()
  221. {
  222. var mockBaseSource = new Mock<IBsonChunkSource>();
  223. var maxChunkSize = Reflector.DefaultMaxChunkSize * 2;
  224. var subject = new OutputBufferChunkSource(mockBaseSource.Object, maxChunkSize: maxChunkSize);
  225. var result = subject.MaxChunkSize;
  226. result.Should().Be(maxChunkSize);
  227. }
  228. [Fact]
  229. public void MinChunkSize_get_should_return_expected_result()
  230. {
  231. var mockBaseSource = new Mock<IBsonChunkSource>();
  232. var minChunkSize = Reflector.DefaultMinChunkSize * 2;
  233. var subject = new OutputBufferChunkSource(mockBaseSource.Object, minChunkSize: minChunkSize);
  234. var result = subject.MinChunkSize;
  235. result.Should().Be(minChunkSize);
  236. }
  237. // nested types
  238. private class Reflector
  239. {
  240. #region static
  241. public static int DefaultInitialUnpooledChunkSize
  242. {
  243. get
  244. {
  245. var field = typeof(OutputBufferChunkSource).GetField("DefaultInitialUnpooledChunkSize", BindingFlags.NonPublic | BindingFlags.Static);
  246. return (int)field.GetValue(null);
  247. }
  248. }
  249. public static int DefaultMaxChunkSize
  250. {
  251. get
  252. {
  253. var field = typeof(OutputBufferChunkSource).GetField("DefaultMaxChunkSize", BindingFlags.NonPublic | BindingFlags.Static);
  254. return (int)field.GetValue(null);
  255. }
  256. }
  257. public static int DefaultMinChunkSize
  258. {
  259. get
  260. {
  261. var field = typeof(OutputBufferChunkSource).GetField("DefaultMinChunkSize", BindingFlags.NonPublic | BindingFlags.Static);
  262. return (int)field.GetValue(null);
  263. }
  264. }
  265. #endregion
  266. private readonly OutputBufferChunkSource _instance;
  267. public Reflector(OutputBufferChunkSource instance)
  268. {
  269. _instance = instance;
  270. }
  271. public bool _disposed
  272. {
  273. get
  274. {
  275. var field = typeof(OutputBufferChunkSource).GetField("_disposed", BindingFlags.NonPublic | BindingFlags.Instance);
  276. return (bool)field.GetValue(_instance);
  277. }
  278. }
  279. }
  280. }
  281. }