Files
sqltoolsservice/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Metadata/MetadataServiceTests.cs
Aasim Khan 73c2a75fba Creating a new Sql Core project that stores OE classes. (#2165)
* init

* More fixes

* moving filters from contracts to core OE classes

* Fixing some tests

* More fixes and added doc comments

* Fixing tests

* Quick refactoring

* more cleanups

* cleanup

* Adding stateless OE

* Adding null checks

* Making group by schema independent of settings

* Fixing tests

* Removing node info from core oe code

* Fixing tests and moving OE code to its own project

* moving oe to own project

* Removing changes to Kusto

* Removing azure access token from service layer

* Fixing project description and title

* Fixing file name typo

* Removing unused  strings from service layer

* Fixing localized strings in tests
Adding comments to stateless OE

* Fixing stuff

* Update src/Microsoft.SqlTools.SqlCore/Microsoft.SqlTools.SqlCore.csproj

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Fixing project nesting

* Fixing more stuff and removing OE class

* Cleanup

* Code cleanup

* fixing oe service provider

* Fixing test name

* Remove using

* Update src/Microsoft.SqlTools.SqlCore/ObjectExplorer/SmoModel/SmoQueryContext.cs

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Fixing syntax error

* Adding project to locproject

* Fixing stuff

* Fixing errors

* sorting usings

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
2023-08-16 22:11:35 -07:00

273 lines
10 KiB
C#

//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using Microsoft.SqlTools.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.Metadata;
using Microsoft.SqlTools.ServiceLayer.Metadata.Contracts;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using Moq;
using System;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using static Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility.LiveConnectionHelper;
using Microsoft.SqlTools.SqlCore.Metadata;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Metadata
{
/// <summary>
/// Tests for the Metadata service component
/// </summary>
public class MetadataServiceTests
{
private string testTableSchema = "dbo";
private string testTableName = "MetadataTestTable";
private LiveConnectionHelper.TestConnectionResult GetLiveAutoCompleteTestObjects()
{
var textDocument = new TextDocumentPosition
{
TextDocument = new TextDocumentIdentifier { Uri = Test.Common.Constants.OwnerUri },
Position = new Position
{
Line = 0,
Character = 0
}
};
var result = LiveConnectionHelper.InitLiveConnectionInfo();
result.TextDocumentPosition = textDocument;
return result;
}
private void CreateTestTable(SqlConnection sqlConn)
{
string sql = string.Format("IF OBJECT_ID('{0}.{1}', 'U') IS NULL CREATE TABLE {0}.{1}(id int)",
this.testTableSchema, this.testTableName);
using (var sqlCommand = new SqlCommand(sql, sqlConn))
{
sqlCommand.ExecuteNonQuery();
}
}
private void DeleteTestTable(SqlConnection sqlConn)
{
string sql = string.Format("IF OBJECT_ID('{0}.{1}', 'U') IS NOT NULL DROP TABLE {0}.{1}",
this.testTableSchema, this.testTableName);
using (var sqlCommand = new SqlCommand(sql, sqlConn))
{
sqlCommand.ExecuteNonQuery();
}
}
/// <summary>
/// Verify that the metadata service correctly returns details for user tables
/// </summary>
[Test]
public void MetadataReturnsUserTable()
{
this.testTableName += new Random().Next(1000000, 9999999).ToString();
var result = GetLiveAutoCompleteTestObjects();
var sqlConn = ConnectionService.OpenSqlConnection(result.ConnectionInfo);
Assert.NotNull(sqlConn);
CreateTestTable(sqlConn);
var metadata = new List<ObjectMetadata>();
MetadataService.ReadMetadata(sqlConn, metadata);
Assert.NotNull(metadata.Count > 0);
bool foundTestTable = false;
foreach (var item in metadata)
{
if (string.Equals(item.Schema, this.testTableSchema, StringComparison.OrdinalIgnoreCase)
&& string.Equals(item.Name, this.testTableName, StringComparison.OrdinalIgnoreCase))
{
foundTestTable = true;
break;
}
}
Assert.True(foundTestTable);
DeleteTestTable(sqlConn);
}
[Test]
public async Task GetTableInfoReturnsValidResults()
{
this.testTableName += new Random().Next(1000000, 9999999).ToString();
var result = GetLiveAutoCompleteTestObjects();
var sqlConn = ConnectionService.OpenSqlConnection(result.ConnectionInfo);
CreateTestTable(sqlConn);
var requestContext = new Mock<RequestContext<TableMetadataResult>>();
requestContext.Setup(x => x.SendResult(It.IsAny<TableMetadataResult>())).Returns(Task.FromResult(new object()));
var metadataParmas = new TableMetadataParams
{
OwnerUri = result.ConnectionInfo.OwnerUri,
Schema = this.testTableSchema,
ObjectName = this.testTableName
};
await MetadataService.HandleGetTableRequest(metadataParmas, requestContext.Object);
DeleteTestTable(sqlConn);
requestContext.VerifyAll();
}
[Test]
public async Task GetViewInfoReturnsValidResults()
{
var result = GetLiveAutoCompleteTestObjects();
var requestContext = new Mock<RequestContext<TableMetadataResult>>();
requestContext.Setup(x => x.SendResult(It.IsAny<TableMetadataResult>())).Returns(Task.FromResult(new object()));
var metadataParmas = new TableMetadataParams
{
OwnerUri = result.ConnectionInfo.OwnerUri,
Schema = "sys",
ObjectName = "all_objects"
};
await MetadataService.HandleGetViewRequest(metadataParmas, requestContext.Object);
requestContext.VerifyAll();
}
[Test]
public async Task VerifyMetadataList()
{
string query = @"CREATE TABLE testTable1 (c1 int)
GO
CREATE PROCEDURE testSp1 @StartProductID [int] AS BEGIN Select * from sys.all_columns END
GO
CREATE VIEW testView1 AS SELECT * from sys.all_columns
GO
CREATE FUNCTION testFun1() RETURNS [int] AS BEGIN RETURN 1 END
GO
CREATE FUNCTION [testFun2](@CityID int)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS AccessResult
GO";
List<ObjectMetadata> expectedMetadataList = new List<ObjectMetadata>
{
new ObjectMetadata
{
MetadataType = MetadataType.Table,
MetadataTypeName = "Table",
Name = "testTable1",
Schema = "dbo"
},
new ObjectMetadata
{
MetadataType = MetadataType.SProc,
MetadataTypeName = "StoredProcedure",
Name = "testSp1",
Schema = "dbo"
},
new ObjectMetadata
{
MetadataType = MetadataType.View,
MetadataTypeName = "View",
Name = "testView1",
Schema = "dbo"
},
new ObjectMetadata
{
MetadataType = MetadataType.Function,
MetadataTypeName = "UserDefinedFunction",
Name = "testFun1",
Schema = "dbo"
},
new ObjectMetadata
{
MetadataType = MetadataType.Function,
MetadataTypeName = "UserDefinedFunction",
Name = "testFun2",
Schema = "dbo"
}
};
await VerifyMetadataListCore(query, expectedMetadataList);
}
private async Task VerifyMetadataListCore(string query, List<ObjectMetadata> expectedMetadataList)
{
var testDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, query, "MetadataTests");
try
{
var requestContext = new Mock<RequestContext<MetadataQueryResult>>();
requestContext.Setup(x => x.SendResult(It.IsAny<MetadataQueryResult>())).Returns(Task.FromResult(new object()));
ConnectionService connectionService = LiveConnectionHelper.GetLiveTestConnectionService();
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
{
//Opening a connection to db to lock the db
TestConnectionResult connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync(testDb.DatabaseName, queryTempFile.FilePath, ConnectionType.Default);
MetadataService service = new MetadataService();
await service.HandleMetadataListRequest(new MetadataQueryParams
{
OwnerUri = queryTempFile.FilePath
}, requestContext.Object);
Thread.Sleep(2000);
await service.MetadataListTask;
requestContext.Verify(x => x.SendResult(It.Is<MetadataQueryResult>(r => VerifyResult(r, expectedMetadataList))));
connectionService.Disconnect(new ServiceLayer.Connection.Contracts.DisconnectParams
{
OwnerUri = queryTempFile.FilePath
});
}
}
catch
{
throw;
}
finally
{
await testDb.CleanupAsync();
}
}
private static bool VerifyResult(MetadataQueryResult result, List<ObjectMetadata> expectedMetadataList)
{
if (expectedMetadataList == null)
{
return result.Metadata == null;
}
if(expectedMetadataList.Count != result.Metadata.Length)
{
return false;
}
foreach (ObjectMetadata expected in expectedMetadataList)
{
if (!result.Metadata.Any(x => x.MetadataType == expected.MetadataType && x.MetadataTypeName == expected.MetadataTypeName && x.Name == expected.Name && x.Schema == expected.Schema))
{
return false;
}
}
return true;
}
}
}