Files
sqltoolsservice/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Utility/TestObjects.cs
Kevin Cunnane f3bf330da6 Connect with different properties should actually change context (#307)
* Connect with different properties should actually change context
- Up to now, calling Connect for a previously-connected URI would disconnect, then reconnect ot the original (not new) target. WIth these changes we handle changes to database name or other key properties by updating the ConnectionInfo and connecting to the new target
- Some interesting scenarios are raised by our API, notably that an empty database name maps to the default DB (which we know nothing about). This limits the new feature such that only if the DB Name is specified, we'll change the connection. Hence 2 calls to an empty DB will not result in a DB change.

Additional changes:
- After discussion with Ben, we're simplifying the cancellation logic. He had made changes to support this, so the main update is that we dispose the token in the final block after its last use (hence avoiding a disposed exception) and clean up the number of Waits required since we already have async cancellation support
- Factored some logic such that the OnConnection callback isn't invoked until after we've updated the database name in the GetConnectionCompleteParams method. Again, this supports reporting the actual DB name instead of leaving it blank for default DB requests.

* PR comment fixes
2017-04-06 11:25:59 -07:00

236 lines
6.9 KiB
C#

//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using Moq;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility
{
/// <summary>
/// Tests for the ServiceHost Connection Service tests
/// </summary>
public class TestObjects
{
public const string ScriptUri = "file://some/file.sql";
/// <summary>
/// Creates a test connection service
/// </summary>
public static ConnectionService GetTestConnectionService()
{
// use mock database connection
return new ConnectionService(new TestSqlConnectionFactory());
}
/// <summary>
/// Creates a test connection info instance.
/// </summary>
public static ConnectionInfo GetTestConnectionInfo()
{
return new ConnectionInfo(
new TestSqlConnectionFactory(),
ScriptUri,
GetTestConnectionDetails());
}
public static ConnectParams GetTestConnectionParams()
{
return new ConnectParams()
{
OwnerUri = ScriptUri,
Connection = GetTestConnectionDetails()
};
}
/// <summary>
/// Creates a test connection details object
/// </summary>
public static ConnectionDetails GetTestConnectionDetails()
{
return new ConnectionDetails()
{
UserName = "user",
Password = "password",
DatabaseName = "databaseName",
ServerName = "serverName"
};
}
/// <summary>
/// Create a test language service instance
/// </summary>
/// <returns></returns>
public static LanguageService GetTestLanguageService()
{
return new LanguageService();
}
/// <summary>
/// Creates and returns a dummy TextDocumentPosition
/// </summary>
public static TextDocumentPosition GetTestDocPosition()
{
return new TextDocumentPosition
{
TextDocument = new TextDocumentIdentifier { Uri = ScriptUri },
Position = new Position
{
Line = 0,
Character = 0
}
};
}
}
/// <summary>
/// Test mock class for IDbCommand
/// </summary>
public class TestSqlCommand : DbCommand
{
internal TestSqlCommand(TestResultSet[] data)
{
Data = data;
var mockParameterCollection = new Mock<DbParameterCollection>();
mockParameterCollection.Setup(c => c.Add(It.IsAny<object>()))
.Callback<object>(d => listParams.Add((DbParameter)d));
mockParameterCollection.Setup(c => c.AddRange(It.IsAny<Array>()))
.Callback<Array>(d => listParams.AddRange(d.Cast<DbParameter>()));
mockParameterCollection.Setup(c => c.Count)
.Returns(() => listParams.Count);
DbParameterCollection = mockParameterCollection.Object;
}
internal TestResultSet[] Data { get; set; }
public override void Cancel()
{
throw new NotImplementedException();
}
public override int ExecuteNonQuery()
{
throw new NotImplementedException();
}
public override object ExecuteScalar()
{
throw new NotImplementedException();
}
public override void Prepare()
{
throw new NotImplementedException();
}
public override string CommandText { get; set; }
public override int CommandTimeout { get; set; }
public override CommandType CommandType { get; set; }
public override UpdateRowSource UpdatedRowSource { get; set; }
protected override DbConnection DbConnection { get; set; }
protected override DbParameterCollection DbParameterCollection { get; }
protected override DbTransaction DbTransaction { get; set; }
public override bool DesignTimeVisible { get; set; }
protected override DbParameter CreateDbParameter()
{
throw new NotImplementedException();
}
protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
{
return new TestDbDataReader(Data);
}
private List<DbParameter> listParams = new List<DbParameter>();
}
/// <summary>
/// Test mock class for SqlConnection wrapper
/// </summary>
public class TestSqlConnection : DbConnection
{
private string _database;
internal TestSqlConnection(TestResultSet[] data)
{
Data = data;
}
internal TestResultSet[] Data { get; set; }
protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
{
throw new NotImplementedException();
}
public override void Close()
{
// No Op
}
public override void Open()
{
// No Op, unless credentials are bad
if(ConnectionString.Contains("invalidUsername"))
{
throw new Exception("Invalid credentials provided");
}
}
public override string ConnectionString { get; set; }
public override string Database
{
get { return _database; }
}
public override ConnectionState State { get; }
public override string DataSource { get; }
public override string ServerVersion { get; }
protected override DbCommand CreateDbCommand()
{
return new TestSqlCommand(Data);
}
public override void ChangeDatabase(string databaseName)
{
// No Op
}
/// <summary>
/// Test helper method to set the database value
/// </summary>
/// <param name="database"></param>
public void SetDatabase(string database)
{
this._database = database;
}
}
/// <summary>
/// Test mock class for SqlConnection factory
/// </summary>
public class TestSqlConnectionFactory : ISqlConnectionFactory
{
public DbConnection CreateSqlConnection(string connectionString)
{
return new TestSqlConnection(null)
{
ConnectionString = connectionString
};
}
}
}