From 5f76f7362f1d9ec03a1a0d0a4cb415f0d8140ede Mon Sep 17 00:00:00 2001 From: howryu Date: Thu, 19 Jul 2018 09:42:09 -0700 Subject: [PATCH] Add mock tests to test session renew --- .../Mock/MockRestSessionExpired.cs | 120 +++++++++++++++ .../Mock/MockRestSessionExpiredInQueryExec.cs | 139 ++++++++++++++++++ Snowflake.Data.Tests/SFStatementTest.cs | 41 ++++++ .../Snowflake.Data.Tests.csproj | 5 + Snowflake.Data/Core/SFSession.cs | 9 +- Snowflake.Data/Core/SFStatement.cs | 7 +- Snowflake.Data/Core/Snowflake.cs | 2 + Snowflake.Data/Snowflake.Data.csproj | 1 - 8 files changed, 319 insertions(+), 5 deletions(-) create mode 100755 Snowflake.Data.Tests/Mock/MockRestSessionExpired.cs create mode 100755 Snowflake.Data.Tests/Mock/MockRestSessionExpiredInQueryExec.cs create mode 100755 Snowflake.Data.Tests/SFStatementTest.cs create mode 100755 Snowflake.Data/Core/Snowflake.cs diff --git a/Snowflake.Data.Tests/Mock/MockRestSessionExpired.cs b/Snowflake.Data.Tests/Mock/MockRestSessionExpired.cs new file mode 100755 index 000000000..15038562a --- /dev/null +++ b/Snowflake.Data.Tests/Mock/MockRestSessionExpired.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using System.Threading; +using System.Net.Http; + +namespace Snowflake.Data.Tests.Mock +{ + using Snowflake.Data.Core; + + class MockRestSessionExpired : IRestRequest + { + static private readonly String EXPIRED_SESSION_TOKEN="session_expired_token"; + + static private readonly String TOKEN_FMT = "Snowflake Token=\"{0}\""; + + static private readonly int SESSION_EXPIRED_CODE = 390112; + + public MockRestSessionExpired() { } + + public Task PostAsync(SFRestRequest postRequest, CancellationToken cancellationToken) + { + if (postRequest.jsonBody is AuthnRequest) + { + AuthnResponse authnResponse = new AuthnResponse + { + data = new AuthnResponseData() + { + token = EXPIRED_SESSION_TOKEN, + masterToken = "master_token", + authResponseSessionInfo = new SessionInfo(), + nameValueParameter = new List() + }, + success = true + }; + + // login request return success + return Task.FromResult((T)(object)authnResponse); + } + else if (postRequest.jsonBody is QueryRequest) + { + if (postRequest.authorizationToken.Equals(String.Format(TOKEN_FMT, EXPIRED_SESSION_TOKEN))) + { + QueryExecResponse queryExecResponse = new QueryExecResponse + { + success = false, + code = SESSION_EXPIRED_CODE + }; + return Task.FromResult((T)(object)queryExecResponse); + } + else if (postRequest.authorizationToken.Equals(String.Format(TOKEN_FMT, "new_session_token"))) + { + QueryExecResponse queryExecResponse = new QueryExecResponse + { + success = true, + data = new QueryExecResponseData + { + rowSet = new string[,] { { "1" } }, + rowType = new List() + { + new ExecResponseRowType + { + name = "colone", + type = "FIXED" + } + }, + parameters = new List() + } + }; + return Task.FromResult((T)(object)queryExecResponse); + } + else + { + QueryExecResponse queryExecResponse = new QueryExecResponse + { + success = false, + code = 1 + }; + return Task.FromResult((T)(object)queryExecResponse); + } + } + else if (postRequest.jsonBody is RenewSessionRequest) + { + return Task.FromResult((T)(object)new RenewSessionResponse + { + success = true, + data = new RenewSessionResponseData() + { + sessionToken = "new_session_token" + } + }); + } + else + { + return Task.FromResult((T)(object)null); + } + } + + public T Post(SFRestRequest postRequest) + { + return Task.Run(async () => await PostAsync(postRequest, CancellationToken.None)).Result; + } + + public T Get(SFRestRequest request) + { + return Task.Run(async () => await GetAsync(request, CancellationToken.None)).Result; + } + + public Task GetAsync(SFRestRequest request, CancellationToken cancellationToken) + { + return Task.FromResult((T)(object)null); + } + + public Task GetAsync(S3DownloadRequest request, CancellationToken cancellationToken) + { + return Task.FromResult(null); + } + } +} diff --git a/Snowflake.Data.Tests/Mock/MockRestSessionExpiredInQueryExec.cs b/Snowflake.Data.Tests/Mock/MockRestSessionExpiredInQueryExec.cs new file mode 100755 index 000000000..76f0099a4 --- /dev/null +++ b/Snowflake.Data.Tests/Mock/MockRestSessionExpiredInQueryExec.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using System.Net.Http; + +namespace Snowflake.Data.Tests.Mock +{ + using Snowflake.Data.Core; + + class MockRestSessionExpiredInQueryExec : IRestRequest + { + static private readonly int QUERY_IN_EXEC_CODE = 333333; + + static private readonly int SESSION_EXPIRED_CODE = 390112; + + private int getResultCallCount = 0; + + public MockRestSessionExpiredInQueryExec() { } + + public Task PostAsync(SFRestRequest postRequest, CancellationToken cancellationToken) + { + if (postRequest.jsonBody is AuthnRequest) + { + AuthnResponse authnResponse = new AuthnResponse + { + data = new AuthnResponseData() + { + token = "session_token", + masterToken = "master_token", + authResponseSessionInfo = new SessionInfo(), + nameValueParameter = new List() + }, + success = true + }; + + // login request return success + return Task.FromResult((T)(object)authnResponse); + } + else if (postRequest.jsonBody is QueryRequest) + { + QueryExecResponse queryExecResponse = new QueryExecResponse + { + success = false, + code = QUERY_IN_EXEC_CODE + }; + return Task.FromResult((T)(object)queryExecResponse); + + } + else if (postRequest.jsonBody is RenewSessionRequest) + { + return Task.FromResult((T)(object)new RenewSessionResponse + { + success = true, + data = new RenewSessionResponseData() + { + sessionToken = "new_session_token" + } + }); + } + else + { + return Task.FromResult((T)(object)null); + } + } + + public T Post(SFRestRequest postRequest) + { + return Task.Run(async () => await PostAsync(postRequest, CancellationToken.None)).Result; + } + + public T Get(SFRestRequest request) + { + return Task.Run(async () => await GetAsync(request, CancellationToken.None)).Result; + } + + public Task GetAsync(SFRestRequest request, CancellationToken cancellationToken) + { + if (getResultCallCount == 0) + { + getResultCallCount++; + QueryExecResponse queryExecResponse = new QueryExecResponse + { + success = false, + code = QUERY_IN_EXEC_CODE + }; + return Task.FromResult((T)(object)queryExecResponse); + } + else if (getResultCallCount == 1) + { + getResultCallCount++; + QueryExecResponse queryExecResponse = new QueryExecResponse + { + success = false, + code = SESSION_EXPIRED_CODE + }; + return Task.FromResult((T)(object)queryExecResponse); + } + else if (getResultCallCount == 2 && + request.authorizationToken.Equals("Snowflake Token=\"new_session_token\"")) + { + getResultCallCount++; + QueryExecResponse queryExecResponse = new QueryExecResponse + { + success = true, + data = new QueryExecResponseData + { + rowSet = new string[,] { { "1" } }, + rowType = new List() + { + new ExecResponseRowType + { + name = "colone", + type = "FIXED" + } + }, + parameters = new List() + } + }; + return Task.FromResult((T)(object)queryExecResponse); + } + else + { + QueryExecResponse queryExecResponse = new QueryExecResponse + { + success = false, + code = 1 + }; + return Task.FromResult((T)(object)queryExecResponse); + } + } + + public Task GetAsync(S3DownloadRequest request, CancellationToken cancellationToken) + { + return Task.FromResult(null); + } + } +} + diff --git a/Snowflake.Data.Tests/SFStatementTest.cs b/Snowflake.Data.Tests/SFStatementTest.cs new file mode 100755 index 000000000..d3e3807d6 --- /dev/null +++ b/Snowflake.Data.Tests/SFStatementTest.cs @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012-2017 Snowflake Computing Inc. All rights reserved. + */ + +namespace Snowflake.Data.Tests +{ + using Snowflake.Data.Core; + using NUnit.Framework; + using System; + + /** + * Mock rest request to test session renew + */ + [TestFixture] + class SFStatementTest + { + [Test] + public void TestSessionRenew() + { + Mock.MockRestSessionExpired rest = new Mock.MockRestSessionExpired(); + SFSession sfSession = new SFSession("account=test;user=test;password=test", null, rest); + sfSession.Open(); + SFStatement statement = new SFStatement(sfSession, rest); + SFBaseResultSet resultSet = statement.Execute(0, "select 1", null, false); + Assert.AreEqual(true, resultSet.Next()); + Assert.AreEqual("1", resultSet.GetString(0)); + } + + [Test] + public void TestSessionRenewDuringQueyrExec() + { + Mock.MockRestSessionExpiredInQueryExec rest = new Mock.MockRestSessionExpiredInQueryExec(); + SFSession sfSession = new SFSession("account=test;user=test;password=test", null, rest); + sfSession.Open(); + SFStatement statement = new SFStatement(sfSession, rest); + SFBaseResultSet resultSet = statement.Execute(0, "select 1", null, false); + Assert.AreEqual(true, resultSet.Next()); + Assert.AreEqual("1", resultSet.GetString(0)); + } + } +} diff --git a/Snowflake.Data.Tests/Snowflake.Data.Tests.csproj b/Snowflake.Data.Tests/Snowflake.Data.Tests.csproj index 3914df521..1e77b1254 100755 --- a/Snowflake.Data.Tests/Snowflake.Data.Tests.csproj +++ b/Snowflake.Data.Tests/Snowflake.Data.Tests.csproj @@ -23,6 +23,11 @@ + + + + + full True diff --git a/Snowflake.Data/Core/SFSession.cs b/Snowflake.Data/Core/SFSession.cs index d55b623a8..811a35ab9 100755 --- a/Snowflake.Data/Core/SFSession.cs +++ b/Snowflake.Data/Core/SFSession.cs @@ -90,9 +90,14 @@ static SFSession() /// Constructor /// /// A string in the form of "key1=value1;key2=value2" - internal SFSession(String connectionString, SecureString password) + internal SFSession(String connectionString, SecureString password) : + this(connectionString, password, RestRequestImpl.Instance) { - restRequest = RestRequestImpl.Instance; + } + + internal SFSession(String connectionString, SecureString password, IRestRequest restRequest) + { + this.restRequest = restRequest; properties = SFSessionProperties.parseConnectionString(connectionString, password); parameterMap = new Dictionary(); diff --git a/Snowflake.Data/Core/SFStatement.cs b/Snowflake.Data/Core/SFStatement.cs index f994e2dda..b76c2e2fb 100755 --- a/Snowflake.Data/Core/SFStatement.cs +++ b/Snowflake.Data/Core/SFStatement.cs @@ -45,12 +45,15 @@ class SFStatement // Cancel callback will be registered under token issued by this source. private CancellationTokenSource _linkedCancellationTokenSouce; - internal SFStatement(SFSession session) + internal SFStatement(SFSession session, IRestRequest rest) { SfSession = session; - _restRequest = RestRequestImpl.Instance; + _restRequest = rest; } + internal SFStatement(SFSession session) : this(session, RestRequestImpl.Instance) + { } + private void AssignQueryRequestId() { lock (_requestIdLock) diff --git a/Snowflake.Data/Core/Snowflake.cs b/Snowflake.Data/Core/Snowflake.cs new file mode 100755 index 000000000..ce42a9afc --- /dev/null +++ b/Snowflake.Data/Core/Snowflake.cs @@ -0,0 +1,2 @@ +using System.Runtime.CompilerServices; +[assembly: InternalsVisibleTo("Snowflake.Data.Tests")] diff --git a/Snowflake.Data/Snowflake.Data.csproj b/Snowflake.Data/Snowflake.Data.csproj index 35947c901..20d5596a7 100755 --- a/Snowflake.Data/Snowflake.Data.csproj +++ b/Snowflake.Data/Snowflake.Data.csproj @@ -43,7 +43,6 @@ -