Example #1
0
        /// <summary>
        /// Writes a raw BSON array.
        /// </summary>
        /// <param name="slice">The byte buffer containing the raw BSON array.</param>
        public virtual void WriteRawBsonArray(IByteBuffer slice)
        {
            // overridden in BsonBinaryWriter to write the raw bytes to the stream
            // for all other streams, deserialize the raw bytes and serialize the resulting array instead

            using (var chunkSource = new InputBufferChunkSource(BsonChunkPool.Default))
                using (var buffer = new MultiChunkBuffer(chunkSource))
                    using (var stream = new ByteBufferStream(buffer))
                    {
                        // wrap the array in a fake document so we can deserialize it
                        var documentLength = slice.Length + 8;
                        buffer.EnsureCapacity(documentLength);
                        stream.WriteInt32(documentLength);
                        stream.WriteBsonType(BsonType.Array);
                        stream.WriteByte((byte)'x');
                        stream.WriteByte(0);
                        stream.WriteSlice(slice);
                        stream.WriteByte(0);
                        buffer.MakeReadOnly();

                        stream.Position = 0;
                        using (var reader = new BsonBinaryReader(stream, BsonBinaryReaderSettings.Defaults))
                        {
                            var deserializationContext = BsonDeserializationContext.CreateRoot(reader);
                            reader.ReadStartDocument();
                            reader.ReadName("x");
                            var array = BsonArraySerializer.Instance.Deserialize(deserializationContext);
                            reader.ReadEndDocument();

                            var serializationContext = BsonSerializationContext.CreateRoot(this);
                            BsonArraySerializer.Instance.Serialize(serializationContext, array);
                        }
                    }
        }
        public void BaseSource_get_should_return_expected_result()
        {
            var baseSource = Substitute.For<IBsonChunkSource>();
            var subject = new InputBufferChunkSource(baseSource);

            var result = subject.BaseSource;

            result.Should().BeSameAs(baseSource);
        }
        public void BaseSource_get_should_return_expected_result()
        {
            var mockBaseSource = new Mock<IBsonChunkSource>();
            var subject = new InputBufferChunkSource(mockBaseSource.Object);

            var result = subject.BaseSource;

            result.Should().BeSameAs(mockBaseSource.Object);
        }
        public void BaseSource_get_should_throw_when_subject_is_disposed()
        {
            var baseSource = Substitute.For<IBsonChunkSource>();
            var subject = new InputBufferChunkSource(baseSource);
            subject.Dispose();

            Action action = () => { var _ = subject.BaseSource; };

            action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("InputBufferChunkSource");
        }
        public void constructor_should_initialize_subject()
        {
            var baseSource = Substitute.For<IBsonChunkSource>();
            var maxUnpooledChunkSize = 2;
            var minChunkSize = 4;
            var maxChunkSize = 8;

            var subject = new InputBufferChunkSource(baseSource, maxUnpooledChunkSize, minChunkSize, maxChunkSize);

            var reflector = new Reflector(subject);
            subject.BaseSource.Should().BeSameAs(baseSource);
            subject.MaxChunkSize.Should().Be(maxChunkSize);
            subject.MaxUnpooledChunkSize.Should().Be(maxUnpooledChunkSize);
            subject.MinChunkSize.Should().Be(minChunkSize);
            reflector._disposed.Should().BeFalse();
        }
        public void MinChunkSize_get_should_return_expected_result()
        {
            var baseSource = Substitute.For<IBsonChunkSource>();
            var minChunkSize = 8 * 1024;
            var subject = new InputBufferChunkSource(baseSource, minChunkSize: minChunkSize);

            var result = subject.MinChunkSize;

            result.Should().Be(minChunkSize);
        }
        public void GetChunk_should_throw_when_requestedSize_is_less_than_or_equal_to_zero(
            [Values(-1, 0)]
            int requestedSize)
        {
            var baseSource = Substitute.For<IBsonChunkSource>();
            var subject = new InputBufferChunkSource(baseSource);

            Action action = () => subject.GetChunk(requestedSize);

            action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("requestedSize");
        }
        public void GetChunk_should_round_requestedSize_to_power_of_2_without_wasting_too_much_space(int requestedSize, int roundedSize)
        {
            var baseSource = Substitute.For<IBsonChunkSource>();
            var subject = new InputBufferChunkSource(baseSource, maxUnpooledChunkSize: 0, minChunkSize: 4, maxChunkSize: 16);
            baseSource.GetChunk(Arg.Any<int>()).Returns(Substitute.For<IBsonChunk>());

            subject.GetChunk(requestedSize);

            baseSource.Received(1).GetChunk(roundedSize);
        }
        public void GetChunk_should_return_unpooled_chunk_when_requestedSize_is_less_than_or_equal_to_maxUnpooledChunkSize(
            [Values(1, 2, 4 * 1024 - 1, 4 * 1024)]
            int requestedSize)
        {
            var baseSource = Substitute.For<IBsonChunkSource>();
            var subject = new InputBufferChunkSource(baseSource);

            var result = subject.GetChunk(requestedSize);

            result.Should().BeOfType<ByteArrayChunk>();
            result.Bytes.Count.Should().Be(requestedSize);
            baseSource.DidNotReceive().GetChunk(Arg.Any<int>());
        }
        public void Dispose_should_dispose_subject()
        {
            var baseSource = Substitute.For<IBsonChunkSource>();
            var subject = new InputBufferChunkSource(baseSource);

            subject.Dispose();

            var reflector = new Reflector(subject);
            reflector._disposed.Should().BeTrue();
        }
        public void Dispose_can_be_called_more_than_once()
        {
            var mockBaseSource = new Mock<IBsonChunkSource>();
            var subject = new InputBufferChunkSource(mockBaseSource.Object);

            subject.Dispose();
            subject.Dispose();
        }
 public Reflector(InputBufferChunkSource instance)
 {
     _instance = instance;
 }
        /// <summary>
        /// Writes a raw BSON array.
        /// </summary>
        /// <param name="slice">The byte buffer containing the raw BSON array.</param>
        public virtual void WriteRawBsonArray(IByteBuffer slice)
        {
            // overridden in BsonBinaryWriter to write the raw bytes to the stream
            // for all other streams, deserialize the raw bytes and serialize the resulting array instead

            using (var chunkSource = new InputBufferChunkSource(BsonChunkPool.Default))
            using (var buffer = new MultiChunkBuffer(chunkSource))
            using (var stream = new ByteBufferStream(buffer))
            {
                // wrap the array in a fake document so we can deserialize it
                var documentLength = slice.Length + 8;
                buffer.EnsureCapacity(documentLength);
                stream.WriteInt32(documentLength);
                stream.WriteBsonType(BsonType.Array);
                stream.WriteByte((byte)'x');
                stream.WriteByte(0);
                stream.WriteSlice(slice);
                stream.WriteByte(0);
                buffer.MakeReadOnly();

                stream.Position = 0;
                using (var reader = new BsonBinaryReader(stream, BsonBinaryReaderSettings.Defaults))
                {
                    var deserializationContext = BsonDeserializationContext.CreateRoot(reader);
                    reader.ReadStartDocument();
                    reader.ReadName("x");
                    var array = BsonArraySerializer.Instance.Deserialize(deserializationContext);
                    reader.ReadEndDocument();

                    var serializationContext = BsonSerializationContext.CreateRoot(this);
                    BsonArraySerializer.Instance.Serialize(serializationContext, array);
                }
            }
        }
        public void MinChunkSize_get_should_return_expected_result()
        {
            var mockBaseSource = new Mock<IBsonChunkSource>();
            var minChunkSize = 8 * 1024;
            var subject = new InputBufferChunkSource(mockBaseSource.Object, minChunkSize: minChunkSize);

            var result = subject.MinChunkSize;

            result.Should().Be(minChunkSize);
        }
        public void GetChunk_should_throw_when_subject_is_disposed()
        {
            var mockBaseSource = new Mock<IBsonChunkSource>();
            var subject = new InputBufferChunkSource(mockBaseSource.Object);
            subject.Dispose();

            Action action = () => subject.GetChunk(1);

            action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("InputBufferChunkSource");
        }
        public void GetChunk_should_round_requestedSize_to_power_of_2_without_wasting_too_much_space(int requestedSize, int roundedSize)
        {
            var mockBaseSource = new Mock<IBsonChunkSource>();
            var subject = new InputBufferChunkSource(mockBaseSource.Object, maxUnpooledChunkSize: 0, minChunkSize: 4, maxChunkSize: 16);
            mockBaseSource.Setup(s => s.GetChunk(It.IsAny<int>())).Returns(() => new Mock<IBsonChunk>().Object);

            subject.GetChunk(requestedSize);

            mockBaseSource.Verify(s => s.GetChunk(roundedSize), Times.Once);
        }
        public void GetChunk_should_return_unpooled_chunk_when_requestedSize_is_less_than_or_equal_to_maxUnpooledChunkSize(
            [Values(1, 2, 4 * 1024 - 1, 4 * 1024)]
            int requestedSize)
        {
            var mockBaseSource = new Mock<IBsonChunkSource>();
            var subject = new InputBufferChunkSource(mockBaseSource.Object);

            var result = subject.GetChunk(requestedSize);

            result.Should().BeOfType<ByteArrayChunk>();
            result.Bytes.Count.Should().Be(requestedSize);
            mockBaseSource.Verify(s => s.GetChunk(It.IsAny<int>()), Times.Never);
        }
        public void Dispose_should_dispose_subject()
        {
            var mockBaseSource = new Mock<IBsonChunkSource>();
            var subject = new InputBufferChunkSource(mockBaseSource.Object);

            subject.Dispose();

            var reflector = new Reflector(subject);
            reflector._disposed.Should().BeTrue();
        }
        public void constructor_should_use_default_value_for_minChunkSize()
        {
            var baseSource = Substitute.For<IBsonChunkSource>();

            var subject = new InputBufferChunkSource(baseSource);

            subject.MinChunkSize.Should().Be(16 * 1024);
        }
        public void Dispose_can_be_called_more_than_once()
        {
            var baseSource = Substitute.For<IBsonChunkSource>();
            var subject = new InputBufferChunkSource(baseSource);

            subject.Dispose();
            subject.Dispose();
        }
 private async Task<IByteBuffer> ReceiveBufferAsync()
 {
     try
     {
         var messageSizeBytes = new byte[4];
         await _stream.ReadBytesAsync(messageSizeBytes, 0, 4, _backgroundTaskCancellationToken).ConfigureAwait(false);
         var messageSize = BitConverter.ToInt32(messageSizeBytes, 0);
         var inputBufferChunkSource = new InputBufferChunkSource(BsonChunkPool.Default);
         var buffer = ByteBufferFactory.Create(inputBufferChunkSource, messageSize);
         buffer.Length = messageSize;
         buffer.SetBytes(0, messageSizeBytes, 0, 4);
         await _stream.ReadBytesAsync(buffer, 4, messageSize - 4, _backgroundTaskCancellationToken).ConfigureAwait(false);
         _lastUsedAtUtc = DateTime.UtcNow;
         buffer.MakeReadOnly();
         return buffer;
     }
     catch (Exception ex)
     {
         var wrappedException = WrapException(ex, "receiving a message from the server");
         ConnectionFailed(wrappedException);
         throw wrappedException;
     }
 }
        public void constructor_should_use_default_value_for_minChunkSize()
        {
            var mockBaseSource = new Mock<IBsonChunkSource>();

            var subject = new InputBufferChunkSource(mockBaseSource.Object);

            subject.MinChunkSize.Should().Be(16 * 1024);
        }