예제 #1
0
        public async Task ExecuteSqlAsync_RequestTransactionIsLeftAlonePopulatedWhenPresent()
        {
            var pool          = new FakeSessionPool();
            var pooledSession = PooledSession.FromSessionName(pool, s_sampleSessionName);

            // Make a successful request
            var request = new ExecuteSqlRequest {
                Transaction = new TransactionSelector {
                    Begin = new TransactionOptions {
                        ReadOnly = new TransactionOptions.Types.ReadOnly()
                    }
                }
            };

            pool.Mock.Setup(client => client.ExecuteSqlAsync(request, It.IsAny <CallSettings>()))
            .ReturnsAsync(new ResultSet())
            .Verifiable();
            await pooledSession.ExecuteSqlAsync(request, 5, CancellationToken.None);

            // The call modifies the request's session, but not transaction.
            Assert.Equal(s_sampleSessionName, request.SessionAsSessionName);
            Assert.Equal(TransactionSelector.SelectorOneofCase.Begin, request.Transaction.SelectorCase);
            Assert.Equal(new TransactionOptions.Types.ReadOnly(), request.Transaction.Begin.ReadOnly);

            pool.Mock.Verify();
        }
예제 #2
0
        public void Expiry()
        {
            var pool         = new FakeSessionPool();
            var options      = pool.Options;
            var clock        = pool.Clock;
            var originalTime = clock.GetCurrentDateTimeUtc();

            // If we evict sessions before we refresh them, things get weird.
            Assert.True(options.IdleSessionRefreshDelay < options.PoolEvictionDelay);

            var pooledSession = PooledSession.FromSessionName(pool, s_sampleSessionName);

            Assert.False(pooledSession.ShouldBeEvicted);
            Assert.False(pooledSession.RequiresRefresh);

            // Detect the need for a refresh
            clock.AdvanceTo(originalTime + options.IdleSessionRefreshDelay + OneTick);
            Assert.False(pooledSession.ShouldBeEvicted);
            Assert.True(pooledSession.RequiresRefresh);

            // Detect the need for eviction
            clock.AdvanceTo(originalTime + options.PoolEvictionDelay + OneTick);
            Assert.True(pooledSession.ShouldBeEvicted);
            Assert.True(pooledSession.RequiresRefresh);
        }
예제 #3
0
        public async Task AutoRefreshOnSuccessfulRpc()
        {
            var pool    = new FakeSessionPool();
            var options = pool.Options;
            var clock   = pool.Clock;

            var originalTime  = clock.GetCurrentDateTimeUtc();
            var pooledSession = PooledSession.FromSessionName(pool, s_sampleSessionName);

            var halfRefresh = TimeSpan.FromTicks(options.IdleSessionRefreshDelay.Ticks / 2);

            clock.Advance(halfRefresh);

            // Make a successful request
            var request  = new BeginTransactionRequest();
            var response = new Transaction();

            pool.Mock.Setup(client => client.BeginTransactionAsync(request, It.IsAny <CallSettings>()))
            .ReturnsAsync(response)
            .Verifiable();
            await pooledSession.BeginTransactionAsync(request, 5, CancellationToken.None);

            // The request will have extended the refresh time.
            Assert.Equal(clock.GetCurrentDateTimeUtc() + options.IdleSessionRefreshDelay, pooledSession.RefreshTimeForTest);

            pool.Mock.Verify();
        }
예제 #4
0
        public void ReleaseToPool_ForceDelete()
        {
            var pool          = new FakeSessionPool();
            var pooledSession = PooledSession.FromSessionName(pool, s_sampleSessionName);

            pooledSession.ReleaseToPool(true);
            Assert.True(pool.ReleasedSessionDeleted);
        }
예제 #5
0
        public void ReleaseToPool_NoDelete()
        {
            var pool          = new FakeSessionPool();
            var pooledSession = PooledSession.FromSessionName(pool, s_sampleSessionName);

            pooledSession.ReleaseToPool(false);
            Assert.False(pool.ReleasedSessionDeleted);
        }
        public void ReleaseToPool_ReadOnlyTransactionNotRolledBack()
        {
            var pool          = new FakeSessionPool();
            var pooledSession = CreateWithTransaction(pool, ReadOnly);

            pooledSession.ReleaseToPool(false);
            Assert.Null(pool.RolledBackTransaction);
        }
        public void ReleaseToPool_ReadWriteUncommittedTransactionRolledBack()
        {
            var pool          = new FakeSessionPool();
            var pooledSession = CreateWithTransaction(pool, ReadWrite);

            pooledSession.ReleaseToPool(false);
            Assert.Equal(pool.RolledBackTransaction, pooledSession.TransactionId);
        }
        public void ReleaseToPool_PartitionedDmlTransactionNotRolledBack()
        {
            var pool          = new FakeSessionPool();
            var pooledSession = CreateWithTransaction(pool, PartitionedDml);

            pooledSession.ReleaseToPool(false);
            Assert.Null(pool.RolledBackTransaction);
        }
예제 #9
0
        public void WithTransaction()
        {
            var pool                   = new FakeSessionPool();
            var pooledSession          = PooledSession.FromSessionName(pool, s_sampleSessionName);
            var transactionId          = ByteString.CopyFromUtf8("transaction");
            var mode                   = TransactionOptions.ModeOneofCase.PartitionedDml;
            var sessionWithTransaction = pooledSession.WithTransaction(transactionId, mode);

            Assert.Equal(mode, sessionWithTransaction.TransactionMode);
            Assert.Equal(transactionId, sessionWithTransaction.TransactionId);
            Assert.Equal(s_sampleSessionName, sessionWithTransaction.SessionName);
        }
예제 #10
0
        public async Task ReleaseToPool_FurtherRpcsInvalid()
        {
            var pool          = new FakeSessionPool();
            var pooledSession = PooledSession.FromSessionName(pool, s_sampleSessionName);

            // Release the session immediately
            pooledSession.ReleaseToPool(false);

            // We now can't make RPCs
            await Assert.ThrowsAsync <ObjectDisposedException>(
                () => pooledSession.BeginTransactionAsync(new BeginTransactionRequest(), 5, CancellationToken.None));
        }
예제 #11
0
        public void FromSessionName_BasicProperties()
        {
            var pool = new FakeSessionPool();

            var pooledSession = PooledSession.FromSessionName(pool, s_sampleSessionName);

            Assert.Same(s_sampleSessionName, pooledSession.SessionName);
            Assert.False(pooledSession.ShouldBeEvicted);
            Assert.False(pooledSession.RequiresRefresh);
            Assert.False(pooledSession.ServerExpired);
            Assert.Null(pooledSession.TransactionId);
            Assert.Equal(TransactionOptions.ModeOneofCase.None, pooledSession.TransactionMode);
        }
        public async Task ReleaseToPool_RolledBackTransactionNotRolledBack()
        {
            var pool = new FakeSessionPool();

            pool.Mock.Setup(client => client.RollbackAsync(It.IsAny <RollbackRequest>(), It.IsAny <CallSettings>()))
            .Returns(Task.CompletedTask);

            var pooledSession = CreateWithTransaction(pool, ReadWrite);
            await pooledSession.RollbackAsync(new RollbackRequest(), null);

            pooledSession.ReleaseToPool(false);
            Assert.Null(pool.RolledBackTransaction);
        }
예제 #13
0
        public void ReleaseToPool_SessionExpired()
        {
            var pool          = new FakeSessionPool();
            var pooledSession = PooledSession.FromSessionName(pool, s_sampleSessionName);

            // Let it go past its eviction time
            var clock = pool.Clock;

            clock.Advance(pool.Options.PoolEvictionDelay + OneTick);

            // When we release the session, the pool should delete it even if we didn't ask it to.
            pooledSession.ReleaseToPool(false);
            Assert.True(pool.ReleasedSessionDeleted);
        }
예제 #14
0
        public async Task RequestSessionIsPopulated()
        {
            var pool          = new FakeSessionPool();
            var pooledSession = PooledSession.FromSessionName(pool, s_sampleSessionName);

            // Make a successful request
            var request = new BeginTransactionRequest();

            pool.Mock.Setup(client => client.BeginTransactionAsync(request, It.IsAny <CallSettings>())).ReturnsAsync(new Transaction());
            await pooledSession.BeginTransactionAsync(request, 5, CancellationToken.None);

            // The call modifies the request. (We can't easily check that it was modified before the RPC)
            Assert.Equal(s_sampleSessionName, request.SessionAsSessionName);
        }
예제 #15
0
        public async Task DetectSessionExpiry()
        {
            var pool          = new FakeSessionPool();
            var pooledSession = PooledSession.FromSessionName(pool, s_sampleSessionName);

            // Make a request which fails due to the session not being found (because it has expired).
            var request = new BeginTransactionRequest();

            pool.Mock.Setup(client => client.BeginTransactionAsync(request, It.IsAny <CallSettings>()))
            .ThrowsAsync(new RpcException(new Status(StatusCode.NotFound, "Session not found")));
            await Assert.ThrowsAsync <RpcException>(() => pooledSession.BeginTransactionAsync(request, 5, CancellationToken.None));

            Assert.True(pooledSession.ServerExpired);
        }
예제 #16
0
        public void TransactionConstructor()
        {
            var connection = new SpannerConnection();
            var pool       = new FakeSessionPool();
            var session    = PooledSession.FromSessionName(pool, new SessionName("project", "instance", "database", "session"));

            var transaction = new SpannerTransaction(connection, TransactionMode.ReadWrite, session: session, timestampBound: null);
            var command     = new SpannerBatchCommand(transaction);

            Assert.Empty(command.Commands);
            Assert.Same(connection, command.Connection);
            Assert.Same(transaction, command.Transaction);
            Assert.Equal(SpannerBatchCommandType.None, command.CommandType);
        }
예제 #17
0
        public async Task ReleaseToPool_SessionInvalidatedByServer()
        {
            var pool          = new FakeSessionPool();
            var pooledSession = PooledSession.FromSessionName(pool, s_sampleSessionName);

            // Make a request which fails due to the session not being found (because it has expired).
            var request = new BeginTransactionRequest();

            pool.Mock.Setup(client => client.BeginTransactionAsync(request, It.IsAny <CallSettings>()))
            .ThrowsAsync(new RpcException(new Status(StatusCode.NotFound, "Session not found")));
            await Assert.ThrowsAsync <RpcException>(() => pooledSession.BeginTransactionAsync(request, 5, CancellationToken.None));

            // When we release the session, the pool should delete it even if we didn't ask it to.
            pooledSession.ReleaseToPool(false);
            Assert.True(pool.ReleasedSessionDeleted);
        }
예제 #18
0
        public async Task ExecuteSqlAsync_RequestTransactionIsPopulatedWhenPresent()
        {
            var pool                   = new FakeSessionPool();
            var transactionId          = ByteString.CopyFromUtf8("transaction");
            var mode                   = TransactionOptions.ModeOneofCase.ReadWrite;
            var pooledSession          = PooledSession.FromSessionName(pool, s_sampleSessionName);
            var sessionWithTransaction = pooledSession.WithTransaction(transactionId, mode);

            // Make a successful request
            var request = new ExecuteSqlRequest();

            pool.Mock.Setup(client => client.ExecuteSqlAsync(request, It.IsAny <CallSettings>())).ReturnsAsync(new ResultSet());
            await sessionWithTransaction.ExecuteSqlAsync(request, 5, CancellationToken.None);

            // The call modifies the request. (We can't easily check that it was modified before the RPC)
            Assert.Equal(s_sampleSessionName, request.SessionAsSessionName);
            Assert.Equal(transactionId, request.Transaction.Id);
        }
        public async Task ExecuteBatchDmlAsync_RequestTransactionIsPopulatedWhenNotPresent()
        {
            var pool                   = new FakeSessionPool();
            var transactionId          = ByteString.CopyFromUtf8("transaction");
            var pooledSession          = PooledSession.FromSessionName(pool, s_sampleSessionName);
            var sessionWithTransaction = pooledSession.WithTransaction(transactionId, ReadWrite);

            // Make a successful request
            var request = new ExecuteBatchDmlRequest();

            pool.Mock.Setup(client => client.ExecuteBatchDmlAsync(request, It.IsAny <CallSettings>()))
            .ReturnsAsync(new ExecuteBatchDmlResponse())
            .Verifiable();
            await sessionWithTransaction.ExecuteBatchDmlAsync(request, null);

            // The call modifies the request. (We can't easily check that it was modified before the RPC)
            Assert.Equal(s_sampleSessionName, request.SessionAsSessionName);
            Assert.Equal(transactionId, request.Transaction.Id);

            pool.Mock.Verify();
        }