mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-13 17:23:02 -05:00
Fix script generated for SQL Assessment results (#1058)
* INSERT VALUES has the limit of 1000 rows. Replace with derived table. * Remove NOT NULL restriction from the generated table. * Fix line endings in SQL Assessment source files.
This commit is contained in:
@@ -1,129 +1,129 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Microsoft.SqlServer.Management.Assessment;
|
using Microsoft.SqlServer.Management.Assessment;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts
|
namespace Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parameters for executing a query from a provided string
|
/// Parameters for executing a query from a provided string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AssessmentParams
|
public class AssessmentParams
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the owner uri to get connection from
|
/// Gets or sets the owner uri to get connection from
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string OwnerUri { get; set; }
|
public string OwnerUri { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the target type
|
/// Gets or sets the target type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SqlObjectType TargetType { get; set; }
|
public SqlObjectType TargetType { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes an item returned by SQL Assessment RPC methods
|
/// Describes an item returned by SQL Assessment RPC methods
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AssessmentItemInfo
|
public class AssessmentItemInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets assessment ruleset version.
|
/// Gets or sets assessment ruleset version.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string RulesetVersion { get; set; }
|
public string RulesetVersion { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets assessment ruleset name
|
/// Gets or sets assessment ruleset name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string RulesetName { get; set; }
|
public string RulesetName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets assessed target's type.
|
/// Gets or sets assessed target's type.
|
||||||
/// Supported values: 1 - server, 2 - database.
|
/// Supported values: 1 - server, 2 - database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SqlObjectType TargetType { get; set; }
|
public SqlObjectType TargetType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the assessed object's name.
|
/// Gets or sets the assessed object's name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TargetName { get; set; }
|
public string TargetName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets check's ID.
|
/// Gets or sets check's ID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string CheckId { get; set; }
|
public string CheckId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets tags assigned to this item.
|
/// Gets or sets tags assigned to this item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string[] Tags { get; set; }
|
public string[] Tags { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a display name for this item.
|
/// Gets or sets a display name for this item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DisplayName { get; set; }
|
public string DisplayName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a brief description of the item's purpose.
|
/// Gets or sets a brief description of the item's purpose.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a <see cref="string"/> containing
|
/// Gets or sets a <see cref="string"/> containing
|
||||||
/// an link to a page providing detailed explanation
|
/// an link to a page providing detailed explanation
|
||||||
/// of the best practice.
|
/// of the best practice.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string HelpLink { get; set; }
|
public string HelpLink { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a <see cref="string"/> indicating
|
/// Gets or sets a <see cref="string"/> indicating
|
||||||
/// severity level assigned to this items.
|
/// severity level assigned to this items.
|
||||||
/// Values are: "Information", "Warning", "Critical".
|
/// Values are: "Information", "Warning", "Critical".
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Level { get; set; }
|
public string Level { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generic SQL Assessment Result
|
/// Generic SQL Assessment Result
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">
|
/// <typeparam name="T">
|
||||||
/// Result item's type derived from <see cref="AssessmentItemInfo"/>
|
/// Result item's type derived from <see cref="AssessmentItemInfo"/>
|
||||||
/// </typeparam>
|
/// </typeparam>
|
||||||
public class AssessmentResultData<T>
|
public class AssessmentResultData<T>
|
||||||
where T : AssessmentItemInfo
|
where T : AssessmentItemInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the collection of assessment results.
|
/// Gets the collection of assessment results.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<T> Items { get; } = new List<T>();
|
public List<T> Items { get; } = new List<T>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets SQL Assessment API version.
|
/// Gets or sets SQL Assessment API version.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ApiVersion { get; set; }
|
public string ApiVersion { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generic SQL Assessment Result
|
/// Generic SQL Assessment Result
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">
|
/// <typeparam name="T">
|
||||||
/// Result item's type derived from <see cref="AssessmentItemInfo"/>
|
/// Result item's type derived from <see cref="AssessmentItemInfo"/>
|
||||||
/// </typeparam>
|
/// </typeparam>
|
||||||
public class AssessmentResult<T> : AssessmentResultData<T>
|
public class AssessmentResult<T> : AssessmentResultData<T>
|
||||||
where T : AssessmentItemInfo
|
where T : AssessmentItemInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating
|
/// Gets or sets a value indicating
|
||||||
/// if assessment operation was successful.
|
/// if assessment operation was successful.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Success { get; set; }
|
public bool Success { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets an status message for the operation.
|
/// Gets or sets an status message for the operation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ErrorMessage { get; set; }
|
public string ErrorMessage { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,56 +1,56 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.TaskServices;
|
using Microsoft.SqlTools.ServiceLayer.TaskServices;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts
|
namespace Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parameters for executing a query from a provided string
|
/// Parameters for executing a query from a provided string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenerateScriptParams
|
public class GenerateScriptParams
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a list of assessment result items
|
/// Gets or sets a list of assessment result items
|
||||||
/// to be written to a table
|
/// to be written to a table
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<AssessmentResultItem> Items { get; set; }
|
public List<AssessmentResultItem> Items { get; set; }
|
||||||
|
|
||||||
public TaskExecutionMode TaskExecutionMode { get; set; }
|
public TaskExecutionMode TaskExecutionMode { get; set; }
|
||||||
|
|
||||||
public string TargetServerName { get; set; }
|
public string TargetServerName { get; set; }
|
||||||
|
|
||||||
public string TargetDatabaseName { get; set; }
|
public string TargetDatabaseName { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GenerateScriptResult
|
public class GenerateScriptResult
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating
|
/// Gets or sets a value indicating
|
||||||
/// if assessment operation was successful
|
/// if assessment operation was successful
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Success { get; set; }
|
public bool Success { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets an status message for the operation
|
/// Gets or sets an status message for the operation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ErrorMessage { get; set; }
|
public string ErrorMessage { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets script text
|
/// Gets or sets script text
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Script { get; set; }
|
public string Script { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GenerateScriptRequest
|
public class GenerateScriptRequest
|
||||||
{
|
{
|
||||||
public static readonly
|
public static readonly
|
||||||
RequestType<GenerateScriptParams, ResultStatus> Type =
|
RequestType<GenerateScriptParams, ResultStatus> Type =
|
||||||
RequestType<GenerateScriptParams, ResultStatus>.Create("assessment/generateScript");
|
RequestType<GenerateScriptParams, ResultStatus>.Create("assessment/generateScript");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts
|
namespace Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parameters for executing a query from a provided string
|
/// Parameters for executing a query from a provided string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GetAssessmentItemsParams : AssessmentParams
|
public class GetAssessmentItemsParams : AssessmentParams
|
||||||
{
|
{
|
||||||
// a placeholder for future specialization
|
// a placeholder for future specialization
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes a check used to assess SQL Server objects.
|
/// Describes a check used to assess SQL Server objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CheckInfo : AssessmentItemInfo
|
public class CheckInfo : AssessmentItemInfo
|
||||||
{
|
{
|
||||||
// a placeholder for future specialization
|
// a placeholder for future specialization
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class GetAssessmentItemsRequest
|
public class GetAssessmentItemsRequest
|
||||||
{
|
{
|
||||||
public static readonly RequestType<GetAssessmentItemsParams, AssessmentResult<CheckInfo>> Type =
|
public static readonly RequestType<GetAssessmentItemsParams, AssessmentResult<CheckInfo>> Type =
|
||||||
RequestType<GetAssessmentItemsParams, AssessmentResult<CheckInfo>>.Create(
|
RequestType<GetAssessmentItemsParams, AssessmentResult<CheckInfo>>.Create(
|
||||||
"assessment/getAssessmentItems");
|
"assessment/getAssessmentItems");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,82 +1,82 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts
|
namespace Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parameters for executing a query from a provided string
|
/// Parameters for executing a query from a provided string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class InvokeParams : AssessmentParams
|
public class InvokeParams : AssessmentParams
|
||||||
{
|
{
|
||||||
// a placeholder for future specialization
|
// a placeholder for future specialization
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SQL Assessment result item kind.
|
/// SQL Assessment result item kind.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// SQL Assessment run is a set of checks. Every check
|
/// SQL Assessment run is a set of checks. Every check
|
||||||
/// may return a result item. Normally it is a note containing
|
/// may return a result item. Normally it is a note containing
|
||||||
/// recommendations on improving target's configuration.
|
/// recommendations on improving target's configuration.
|
||||||
/// But some checks may fail to obtain data due to access
|
/// But some checks may fail to obtain data due to access
|
||||||
/// restrictions or data integrity. In this case
|
/// restrictions or data integrity. In this case
|
||||||
/// the check produces an error or a warning.
|
/// the check produces an error or a warning.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public enum AssessmentResultItemKind
|
public enum AssessmentResultItemKind
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SQL Assessment item contains recommendation
|
/// SQL Assessment item contains recommendation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Note = 0,
|
Note = 0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SQL Assessment item contains a warning on
|
/// SQL Assessment item contains a warning on
|
||||||
/// limited assessment capabilities
|
/// limited assessment capabilities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Warning = 1,
|
Warning = 1,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SQL Assessment item contain a description of
|
/// SQL Assessment item contain a description of
|
||||||
/// error occured in the course of assessment run
|
/// error occured in the course of assessment run
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Error = 2
|
Error = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes an assessment result item
|
/// Describes an assessment result item
|
||||||
/// containing a recommendation based on best practices.
|
/// containing a recommendation based on best practices.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AssessmentResultItem : AssessmentItemInfo
|
public class AssessmentResultItem : AssessmentItemInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a message to the user
|
/// Gets or sets a message to the user
|
||||||
/// containing the recommendation.
|
/// containing the recommendation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets result type:
|
/// Gets or sets result type:
|
||||||
/// 0 - real result, 1 - warning, 2 - error.
|
/// 0 - real result, 1 - warning, 2 - error.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public AssessmentResultItemKind Kind { get; set; }
|
public AssessmentResultItemKind Kind { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets date and time
|
/// Gets or sets date and time
|
||||||
/// when the item had been acquired.
|
/// when the item had been acquired.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset Timestamp { get; set; }
|
public DateTimeOffset Timestamp { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class InvokeRequest
|
public class InvokeRequest
|
||||||
{
|
{
|
||||||
public static readonly
|
public static readonly
|
||||||
RequestType<InvokeParams, AssessmentResult<AssessmentResultItem>> Type =
|
RequestType<InvokeParams, AssessmentResult<AssessmentResultItem>> Type =
|
||||||
RequestType<InvokeParams, AssessmentResult<AssessmentResultItem>>.Create("assessment/invoke");
|
RequestType<InvokeParams, AssessmentResult<AssessmentResultItem>>.Create("assessment/invoke");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlAssessment
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the unique id associated with this instance.
|
/// Gets the unique id associated with this instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string OperationId { get; set; }
|
public string OperationId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the parameters containing assessment results
|
/// Gets the parameters containing assessment results
|
||||||
/// to be stored in a data table.
|
/// to be stored in a data table.
|
||||||
@@ -44,8 +44,8 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlAssessment
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the sql task that's executing the operation
|
/// Gets or sets the sql task that's executing the operation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SqlTask SqlTask { get; set; }
|
public SqlTask SqlTask { get; set; }
|
||||||
|
|
||||||
public GenerateScriptOperation(GenerateScriptParams parameters)
|
public GenerateScriptOperation(GenerateScriptParams parameters)
|
||||||
{
|
{
|
||||||
Validate.IsNotNull(nameof(parameters), parameters);
|
Validate.IsNotNull(nameof(parameters), parameters);
|
||||||
@@ -92,24 +92,29 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlAssessment
|
|||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
const string scriptPrologue =
|
const string scriptPrologue =
|
||||||
@"IF (NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'AssessmentResult'))
|
@"IF (NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'AssessmentResult'))
|
||||||
BEGIN
|
BEGIN
|
||||||
CREATE TABLE [dbo].[AssessmentResult](
|
CREATE TABLE [dbo].[AssessmentResult](
|
||||||
[CheckName] [nvarchar](max) NOT NULL,
|
[CheckName] [nvarchar](max),
|
||||||
[CheckId] [nvarchar](max) NOT NULL,
|
[CheckId] [nvarchar](max),
|
||||||
[RulesetName] [nvarchar](max) NOT NULL,
|
[RulesetName] [nvarchar](max),
|
||||||
[RulesetVersion] [nvarchar](max) NOT NULL,
|
[RulesetVersion] [nvarchar](max),
|
||||||
[Severity] [nvarchar](max) NOT NULL,
|
[Severity] [nvarchar](max),
|
||||||
[Message] [nvarchar](max) NOT NULL,
|
[Message] [nvarchar](max),
|
||||||
[TargetPath] [nvarchar](max) NOT NULL,
|
[TargetPath] [nvarchar](max),
|
||||||
[TargetType] [nvarchar](max) NOT NULL,
|
[TargetType] [nvarchar](max),
|
||||||
[HelpLink] [nvarchar](max) NOT NULL,
|
[HelpLink] [nvarchar](max),
|
||||||
[Timestamp] [datetimeoffset](7) NOT NULL
|
[Timestamp] [datetimeoffset](7)
|
||||||
)
|
)
|
||||||
END
|
END
|
||||||
GO
|
GO
|
||||||
INSERT INTO [dbo].[AssessmentResult] ([CheckName],[CheckId],[RulesetName],[RulesetVersion],[Severity],[Message],[TargetPath],[TargetType],[HelpLink],[Timestamp])
|
INSERT INTO [dbo].[AssessmentResult] ([CheckName],[CheckId],[RulesetName],[RulesetVersion],[Severity],[Message],[TargetPath],[TargetType],[HelpLink],[Timestamp])
|
||||||
VALUES";
|
SELECT rpt.[CheckName],rpt.[CheckId],rpt.[RulesetName],rpt.[RulesetVersion],rpt.[Severity],rpt.[Message],rpt.[TargetPath],rpt.[TargetType],rpt.[HelpLink],rpt.[Timestamp]
|
||||||
|
FROM (VALUES ";
|
||||||
|
|
||||||
|
const string scriptEpilogue =
|
||||||
|
@"
|
||||||
|
) rpt([CheckName],[CheckId],[RulesetName],[RulesetVersion],[Severity],[Message],[TargetPath],[TargetType],[HelpLink],[Timestamp])";
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
if (generateScriptParams.Items != null)
|
if (generateScriptParams.Items != null)
|
||||||
@@ -122,11 +127,14 @@ VALUES";
|
|||||||
if (item.Kind == AssessmentResultItemKind.Note)
|
if (item.Kind == AssessmentResultItemKind.Note)
|
||||||
{
|
{
|
||||||
sb.Append(
|
sb.Append(
|
||||||
$"\r\n('{CUtils.EscapeStringSQuote(item.DisplayName)}','{CUtils.EscapeStringSQuote(item.CheckId)}','{CUtils.EscapeStringSQuote(item.RulesetName)}','{item.RulesetVersion}','{item.Level}','{CUtils.EscapeStringSQuote(item.Message)}','{CUtils.EscapeStringSQuote(item.TargetName)}','{item.TargetType}','{CUtils.EscapeStringSQuote(item.HelpLink)}','{item.Timestamp:yyyy-MM-dd hh:mm:ss.fff zzz}'),");
|
$@"
|
||||||
|
('{CUtils.EscapeStringSQuote(item.DisplayName)}','{CUtils.EscapeStringSQuote(item.CheckId)}','{CUtils.EscapeStringSQuote(item.RulesetName)}','{item.RulesetVersion}','{item.Level}','{CUtils.EscapeStringSQuote(item.Message)}','{CUtils.EscapeStringSQuote(item.TargetName)}','{item.TargetType}','{CUtils.EscapeStringSQuote(item.HelpLink)}','{item.Timestamp:yyyy-MM-dd hh:mm:ss.fff zzz}'),");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.Length -= 1;
|
sb.Length -= 1;
|
||||||
|
|
||||||
|
sb.Append(scriptEpilogue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,225 +1,225 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Microsoft.SqlServer.Management.Assessment;
|
using Microsoft.SqlServer.Management.Assessment;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
|
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
|
||||||
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
|
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
|
||||||
using Microsoft.SqlTools.ServiceLayer.SqlAssessment;
|
using Microsoft.SqlTools.ServiceLayer.SqlAssessment;
|
||||||
using Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Test.Common;
|
using Microsoft.SqlTools.ServiceLayer.Test.Common;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SqlAssessment
|
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SqlAssessment
|
||||||
{
|
{
|
||||||
public class SqlAssessmentServiceTests
|
public class SqlAssessmentServiceTests
|
||||||
{
|
{
|
||||||
private delegate Task<List<TResult>> AssessmentMethod<TResult>(SqlObjectLocator locator);
|
private delegate Task<List<TResult>> AssessmentMethod<TResult>(SqlObjectLocator locator);
|
||||||
|
|
||||||
private static readonly string[] AllowedSeverityLevels = { "Information", "Warning", "Critical" };
|
private static readonly string[] AllowedSeverityLevels = { "Information", "Warning", "Critical" };
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task InvokeSqlAssessmentServerTest()
|
public async Task InvokeSqlAssessmentServerTest()
|
||||||
{
|
{
|
||||||
var liveConnection = LiveConnectionHelper.InitLiveConnectionInfo("master");
|
var liveConnection = LiveConnectionHelper.InitLiveConnectionInfo("master");
|
||||||
|
|
||||||
var connection = liveConnection.ConnectionInfo.AllConnections.FirstOrDefault();
|
var connection = liveConnection.ConnectionInfo.AllConnections.FirstOrDefault();
|
||||||
Debug.Assert(connection != null, "Live connection is always expected providing a connection");
|
Debug.Assert(connection != null, "Live connection is always expected providing a connection");
|
||||||
|
|
||||||
var serverInfo = ReliableConnectionHelper.GetServerVersion(connection);
|
var serverInfo = ReliableConnectionHelper.GetServerVersion(connection);
|
||||||
|
|
||||||
var response = await CallAssessment<AssessmentResultItem>(
|
var response = await CallAssessment<AssessmentResultItem>(
|
||||||
nameof(SqlAssessmentService.InvokeSqlAssessment),
|
nameof(SqlAssessmentService.InvokeSqlAssessment),
|
||||||
SqlObjectType.Server,
|
SqlObjectType.Server,
|
||||||
liveConnection);
|
liveConnection);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(response.Items.Select(i => i.Message), Has.All.Not.Null.Or.Empty);
|
Assert.That(response.Items.Select(i => i.Message), Has.All.Not.Null.Or.Empty);
|
||||||
Assert.That(response.Items.Select(i => i.TargetName), Has.All.EqualTo(serverInfo.ServerName));
|
Assert.That(response.Items.Select(i => i.TargetName), Has.All.EqualTo(serverInfo.ServerName));
|
||||||
foreach (var i in response.Items.Where(i => i.Kind == 0))
|
foreach (var i in response.Items.Where(i => i.Kind == 0))
|
||||||
{
|
{
|
||||||
AssertInfoPresent(i);
|
AssertInfoPresent(i);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task GetAssessmentItemsServerTest()
|
public async Task GetAssessmentItemsServerTest()
|
||||||
{
|
{
|
||||||
var liveConnection = LiveConnectionHelper.InitLiveConnectionInfo("master");
|
var liveConnection = LiveConnectionHelper.InitLiveConnectionInfo("master");
|
||||||
|
|
||||||
var connection = liveConnection.ConnectionInfo.AllConnections.FirstOrDefault();
|
var connection = liveConnection.ConnectionInfo.AllConnections.FirstOrDefault();
|
||||||
Debug.Assert(connection != null, "Live connection is always expected providing a connection");
|
Debug.Assert(connection != null, "Live connection is always expected providing a connection");
|
||||||
|
|
||||||
var serverInfo = ReliableConnectionHelper.GetServerVersion(connection);
|
var serverInfo = ReliableConnectionHelper.GetServerVersion(connection);
|
||||||
|
|
||||||
var response = await CallAssessment<CheckInfo>(
|
var response = await CallAssessment<CheckInfo>(
|
||||||
nameof(SqlAssessmentService.GetAssessmentItems),
|
nameof(SqlAssessmentService.GetAssessmentItems),
|
||||||
SqlObjectType.Server,
|
SqlObjectType.Server,
|
||||||
liveConnection);
|
liveConnection);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(response.Items.Select(i => i.TargetName), Has.All.EqualTo(serverInfo.ServerName));
|
Assert.That(response.Items.Select(i => i.TargetName), Has.All.EqualTo(serverInfo.ServerName));
|
||||||
foreach (var i in response.Items)
|
foreach (var i in response.Items)
|
||||||
{
|
{
|
||||||
AssertInfoPresent(i);
|
AssertInfoPresent(i);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task GetAssessmentItemsDatabaseTest()
|
public async Task GetAssessmentItemsDatabaseTest()
|
||||||
{
|
{
|
||||||
const string DatabaseName = "tempdb";
|
const string DatabaseName = "tempdb";
|
||||||
var liveConnection = LiveConnectionHelper.InitLiveConnectionInfo(DatabaseName);
|
var liveConnection = LiveConnectionHelper.InitLiveConnectionInfo(DatabaseName);
|
||||||
var response = await CallAssessment<CheckInfo>(
|
var response = await CallAssessment<CheckInfo>(
|
||||||
nameof(SqlAssessmentService.GetAssessmentItems),
|
nameof(SqlAssessmentService.GetAssessmentItems),
|
||||||
SqlObjectType.Database,
|
SqlObjectType.Database,
|
||||||
liveConnection);
|
liveConnection);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(response.Items.Select(i => i.TargetName), Has.All.EndsWith(":" + DatabaseName));
|
Assert.That(response.Items.Select(i => i.TargetName), Has.All.EndsWith(":" + DatabaseName));
|
||||||
foreach (var i in response.Items)
|
foreach (var i in response.Items)
|
||||||
{
|
{
|
||||||
AssertInfoPresent(i);
|
AssertInfoPresent(i);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task InvokeSqlAssessmentIDatabaseTest()
|
public async Task InvokeSqlAssessmentIDatabaseTest()
|
||||||
{
|
{
|
||||||
const string DatabaseName = "tempdb";
|
const string DatabaseName = "tempdb";
|
||||||
var liveConnection = LiveConnectionHelper.InitLiveConnectionInfo(DatabaseName);
|
var liveConnection = LiveConnectionHelper.InitLiveConnectionInfo(DatabaseName);
|
||||||
var response = await CallAssessment<AssessmentResultItem>(
|
var response = await CallAssessment<AssessmentResultItem>(
|
||||||
nameof(SqlAssessmentService.InvokeSqlAssessment),
|
nameof(SqlAssessmentService.InvokeSqlAssessment),
|
||||||
SqlObjectType.Database,
|
SqlObjectType.Database,
|
||||||
liveConnection);
|
liveConnection);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(response.Items.Select(i => i.Message), Has.All.Not.Null.Or.Empty);
|
Assert.That(response.Items.Select(i => i.Message), Has.All.Not.Null.Or.Empty);
|
||||||
Assert.That(response.Items.Select(i => i.TargetName), Has.All.EndsWith(":" + DatabaseName));
|
Assert.That(response.Items.Select(i => i.TargetName), Has.All.EndsWith(":" + DatabaseName));
|
||||||
foreach (var i in response.Items.Where(i => i.Kind == 0))
|
foreach (var i in response.Items.Where(i => i.Kind == 0))
|
||||||
{
|
{
|
||||||
AssertInfoPresent(i);
|
AssertInfoPresent(i);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<AssessmentResult<TResult>> CallAssessment<TResult>(
|
private static async Task<AssessmentResult<TResult>> CallAssessment<TResult>(
|
||||||
string methodName,
|
string methodName,
|
||||||
SqlObjectType sqlObjectType,
|
SqlObjectType sqlObjectType,
|
||||||
LiveConnectionHelper.TestConnectionResult liveConnection)
|
LiveConnectionHelper.TestConnectionResult liveConnection)
|
||||||
where TResult : AssessmentItemInfo
|
where TResult : AssessmentItemInfo
|
||||||
{
|
{
|
||||||
var connInfo = liveConnection.ConnectionInfo;
|
var connInfo = liveConnection.ConnectionInfo;
|
||||||
|
|
||||||
AssessmentResult<TResult> response;
|
AssessmentResult<TResult> response;
|
||||||
|
|
||||||
using (var service = new SqlAssessmentService(
|
using (var service = new SqlAssessmentService(
|
||||||
TestServiceProvider.Instance.ConnectionService,
|
TestServiceProvider.Instance.ConnectionService,
|
||||||
TestServiceProvider.Instance.WorkspaceService))
|
TestServiceProvider.Instance.WorkspaceService))
|
||||||
{
|
{
|
||||||
AddTestRules(service);
|
AddTestRules(service);
|
||||||
|
|
||||||
string randomUri = Guid.NewGuid().ToString();
|
string randomUri = Guid.NewGuid().ToString();
|
||||||
AssessmentParams requestParams =
|
AssessmentParams requestParams =
|
||||||
new AssessmentParams { OwnerUri = randomUri, TargetType = sqlObjectType };
|
new AssessmentParams { OwnerUri = randomUri, TargetType = sqlObjectType };
|
||||||
ConnectParams connectParams = new ConnectParams
|
ConnectParams connectParams = new ConnectParams
|
||||||
{
|
{
|
||||||
OwnerUri = requestParams.OwnerUri,
|
OwnerUri = requestParams.OwnerUri,
|
||||||
Connection = connInfo.ConnectionDetails,
|
Connection = connInfo.ConnectionDetails,
|
||||||
Type = ConnectionType.Default
|
Type = ConnectionType.Default
|
||||||
};
|
};
|
||||||
|
|
||||||
var methodInfo = typeof(SqlAssessmentService).GetMethod(
|
var methodInfo = typeof(SqlAssessmentService).GetMethod(
|
||||||
methodName,
|
methodName,
|
||||||
BindingFlags.Instance | BindingFlags.NonPublic);
|
BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
|
||||||
Assert.NotNull(methodInfo);
|
Assert.NotNull(methodInfo);
|
||||||
|
|
||||||
var func = (AssessmentMethod<TResult>)Delegate.CreateDelegate(
|
var func = (AssessmentMethod<TResult>)Delegate.CreateDelegate(
|
||||||
typeof(AssessmentMethod<TResult>),
|
typeof(AssessmentMethod<TResult>),
|
||||||
service,
|
service,
|
||||||
methodInfo);
|
methodInfo);
|
||||||
|
|
||||||
response = await service.CallAssessmentEngine<TResult>(
|
response = await service.CallAssessmentEngine<TResult>(
|
||||||
requestParams,
|
requestParams,
|
||||||
connectParams,
|
connectParams,
|
||||||
randomUri,
|
randomUri,
|
||||||
t => func(t));
|
t => func(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.NotNull(response);
|
Assert.NotNull(response);
|
||||||
if (response.Success)
|
if (response.Success)
|
||||||
{
|
{
|
||||||
Assert.That(response.Items.Select(i => i.TargetType), Has.All.EqualTo(sqlObjectType));
|
Assert.That(response.Items.Select(i => i.TargetType), Has.All.EqualTo(sqlObjectType));
|
||||||
Assert.That(response.Items.Select(i => i.Level), Has.All.AnyOf(AllowedSeverityLevels));
|
Assert.That(response.Items.Select(i => i.Level), Has.All.AnyOf(AllowedSeverityLevels));
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddTestRules(SqlAssessmentService service)
|
private static void AddTestRules(SqlAssessmentService service)
|
||||||
{
|
{
|
||||||
const string TestRuleset = @"
|
const string TestRuleset = @"
|
||||||
{
|
{
|
||||||
'name': 'Tags & Checks',
|
'name': 'Tags & Checks',
|
||||||
'version': '0.3',
|
'version': '0.3',
|
||||||
'schemaVersion': '1.0',
|
'schemaVersion': '1.0',
|
||||||
'rules': [
|
'rules': [
|
||||||
{
|
{
|
||||||
'id': 'ServerRule',
|
'id': 'ServerRule',
|
||||||
'itemType': 'definition',
|
'itemType': 'definition',
|
||||||
'tags': [ 'Test' ],
|
'tags': [ 'Test' ],
|
||||||
'displayName': 'Test server check',
|
'displayName': 'Test server check',
|
||||||
'description': 'This check always fails for testing purposes.',
|
'description': 'This check always fails for testing purposes.',
|
||||||
'message': 'This check intentionally fails',
|
'message': 'This check intentionally fails',
|
||||||
'target': { 'type': 'Server' }
|
'target': { 'type': 'Server' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id': 'DatabaseRule',
|
'id': 'DatabaseRule',
|
||||||
'itemType': 'definition',
|
'itemType': 'definition',
|
||||||
'tags': [ 'Test' ],
|
'tags': [ 'Test' ],
|
||||||
'displayName': 'Test server check',
|
'displayName': 'Test server check',
|
||||||
'description': 'This check always fails for testing purposes.',
|
'description': 'This check always fails for testing purposes.',
|
||||||
'message': 'This check intentionally fails',
|
'message': 'This check intentionally fails',
|
||||||
'target': { 'type': 'Database' }
|
'target': { 'type': 'Database' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
using (var reader = new StringReader(TestRuleset))
|
using (var reader = new StringReader(TestRuleset))
|
||||||
{
|
{
|
||||||
service.Engine.PushRuleFactoryJson(reader);
|
service.Engine.PushRuleFactoryJson(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AssertInfoPresent(AssessmentItemInfo item)
|
private void AssertInfoPresent(AssessmentItemInfo item)
|
||||||
{
|
{
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(item.CheckId, Is.Not.Null.Or.Empty);
|
Assert.That(item.CheckId, Is.Not.Null.Or.Empty);
|
||||||
Assert.That(item.DisplayName, Is.Not.Null.Or.Empty);
|
Assert.That(item.DisplayName, Is.Not.Null.Or.Empty);
|
||||||
Assert.That(item.Description, Is.Not.Null.Or.Empty);
|
Assert.That(item.Description, Is.Not.Null.Or.Empty);
|
||||||
Assert.NotNull(item.Tags);
|
Assert.NotNull(item.Tags);
|
||||||
Assert.That(item.Tags, Has.All.Not.Null.Or.Empty);
|
Assert.That(item.Tags, Has.All.Not.Null.Or.Empty);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,157 +1,159 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.SqlServer.Management.Assessment;
|
using Microsoft.SqlServer.Management.Assessment;
|
||||||
using Microsoft.SqlTools.ServiceLayer.SqlAssessment;
|
using Microsoft.SqlTools.ServiceLayer.SqlAssessment;
|
||||||
using Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.TaskServices;
|
using Microsoft.SqlTools.ServiceLayer.TaskServices;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.SqlAssessment
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.SqlAssessment
|
||||||
{
|
{
|
||||||
public class GenerateScriptOperationTests
|
public class GenerateScriptOperationTests
|
||||||
{
|
{
|
||||||
private static readonly GenerateScriptParams SampleParams = new GenerateScriptParams
|
private static readonly GenerateScriptParams SampleParams = new GenerateScriptParams
|
||||||
{
|
{
|
||||||
Items = new List<AssessmentResultItem>
|
Items = new List<AssessmentResultItem>
|
||||||
{
|
{
|
||||||
new AssessmentResultItem
|
new AssessmentResultItem
|
||||||
{
|
{
|
||||||
CheckId = "C1",
|
CheckId = "C1",
|
||||||
Description = "Desc1",
|
Description = "Desc1",
|
||||||
DisplayName = "DN1",
|
DisplayName = "DN1",
|
||||||
HelpLink = "HL1",
|
HelpLink = "HL1",
|
||||||
Kind = AssessmentResultItemKind.Note,
|
Kind = AssessmentResultItemKind.Note,
|
||||||
Level = "Information",
|
Level = "Information",
|
||||||
Message = "Msg'1",
|
Message = "Msg'1",
|
||||||
TargetName = "proj[*]_dev",
|
TargetName = "proj[*]_dev",
|
||||||
TargetType = SqlObjectType.Server,
|
TargetType = SqlObjectType.Server,
|
||||||
Timestamp = new DateTimeOffset(2001, 5, 25, 13, 42, 00, TimeSpan.Zero),
|
Timestamp = new DateTimeOffset(2001, 5, 25, 13, 42, 00, TimeSpan.Zero),
|
||||||
RulesetName = "Microsoft Ruleset",
|
RulesetName = "Microsoft Ruleset",
|
||||||
RulesetVersion = "1.3"
|
RulesetVersion = "1.3"
|
||||||
},
|
},
|
||||||
new AssessmentResultItem
|
new AssessmentResultItem
|
||||||
{
|
{
|
||||||
CheckId = "C-2",
|
CheckId = "C-2",
|
||||||
Description = "Desc2",
|
Description = "Desc2",
|
||||||
DisplayName = "D N2",
|
DisplayName = "D N2",
|
||||||
HelpLink = "http://HL2",
|
HelpLink = "http://HL2",
|
||||||
Kind = AssessmentResultItemKind.Warning,
|
Kind = AssessmentResultItemKind.Warning,
|
||||||
Level = "Warning",
|
Level = "Warning",
|
||||||
Message = "Msg'1",
|
Message = "Msg'1",
|
||||||
TargetName = "proj[*]_devW",
|
TargetName = "proj[*]_devW",
|
||||||
TargetType = SqlObjectType.Database,
|
TargetType = SqlObjectType.Database,
|
||||||
Timestamp = new DateTimeOffset(2001, 5, 25, 13, 42, 00, TimeSpan.FromHours(3)),
|
Timestamp = new DateTimeOffset(2001, 5, 25, 13, 42, 00, TimeSpan.FromHours(3)),
|
||||||
RulesetName = "Microsoft Ruleset",
|
RulesetName = "Microsoft Ruleset",
|
||||||
RulesetVersion = "1.3"
|
RulesetVersion = "1.3"
|
||||||
},
|
},
|
||||||
new AssessmentResultItem
|
new AssessmentResultItem
|
||||||
{
|
{
|
||||||
CheckId = "C'3",
|
CheckId = "C'3",
|
||||||
Description = "Des'c3",
|
Description = "Des'c3",
|
||||||
DisplayName = "D'N1",
|
DisplayName = "D'N1",
|
||||||
HelpLink = "HL'1",
|
HelpLink = "HL'1",
|
||||||
Kind = AssessmentResultItemKind.Error,
|
Kind = AssessmentResultItemKind.Error,
|
||||||
Level = "Critical",
|
Level = "Critical",
|
||||||
Message = "Msg'1",
|
Message = "Msg'1",
|
||||||
TargetName = "proj[*]_devE",
|
TargetName = "proj[*]_devE",
|
||||||
TargetType = SqlObjectType.Server,
|
TargetType = SqlObjectType.Server,
|
||||||
Timestamp = new DateTimeOffset(2001, 5, 25, 13, 42, 00, TimeSpan.FromMinutes(-90)),
|
Timestamp = new DateTimeOffset(2001, 5, 25, 13, 42, 00, TimeSpan.FromMinutes(-90)),
|
||||||
RulesetName = "Microsoft Ruleset",
|
RulesetName = "Microsoft Ruleset",
|
||||||
RulesetVersion = "1.3"
|
RulesetVersion = "1.3"
|
||||||
},
|
},
|
||||||
new AssessmentResultItem
|
new AssessmentResultItem
|
||||||
{
|
{
|
||||||
CheckId = "C-2",
|
CheckId = "C-2",
|
||||||
Description = "Desc2",
|
Description = "Desc2",
|
||||||
DisplayName = "D N2",
|
DisplayName = "D N2",
|
||||||
HelpLink = "http://HL2",
|
HelpLink = "http://HL2",
|
||||||
Kind = AssessmentResultItemKind.Note,
|
Kind = AssessmentResultItemKind.Note,
|
||||||
Level = "Warning",
|
Level = "Warning",
|
||||||
Message = "Msg'1",
|
Message = "Msg'1",
|
||||||
TargetName = "proj[*]_dev",
|
TargetName = "proj[*]_dev",
|
||||||
TargetType = SqlObjectType.Database,
|
TargetType = SqlObjectType.Database,
|
||||||
Timestamp = new DateTimeOffset(2001, 5, 25, 13, 42, 00, TimeSpan.FromHours(3)),
|
Timestamp = new DateTimeOffset(2001, 5, 25, 13, 42, 00, TimeSpan.FromHours(3)),
|
||||||
RulesetName = "Microsoft Ruleset",
|
RulesetName = "Microsoft Ruleset",
|
||||||
RulesetVersion = "1.3"
|
RulesetVersion = "1.3"
|
||||||
},
|
},
|
||||||
new AssessmentResultItem
|
new AssessmentResultItem
|
||||||
{
|
{
|
||||||
CheckId = "C'3",
|
CheckId = "C'3",
|
||||||
Description = "Des'c3",
|
Description = "Des'c3",
|
||||||
DisplayName = "D'N1",
|
DisplayName = "D'N1",
|
||||||
HelpLink = "HL'1",
|
HelpLink = "HL'1",
|
||||||
Kind = AssessmentResultItemKind.Note,
|
Kind = AssessmentResultItemKind.Note,
|
||||||
Level = "Critical",
|
Level = "Critical",
|
||||||
Message = "Msg'1",
|
Message = "Msg'1",
|
||||||
TargetName = "proj[*]_dev",
|
TargetName = "proj[*]_dev",
|
||||||
TargetType = SqlObjectType.Server,
|
TargetType = SqlObjectType.Server,
|
||||||
Timestamp = new DateTimeOffset(2001, 5, 25, 13, 42, 00, TimeSpan.FromMinutes(-90)),
|
Timestamp = new DateTimeOffset(2001, 5, 25, 13, 42, 00, TimeSpan.FromMinutes(-90)),
|
||||||
RulesetName = "Microsoft Ruleset",
|
RulesetName = "Microsoft Ruleset",
|
||||||
RulesetVersion = "1.3"
|
RulesetVersion = "1.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private const string SampleScript =
|
private const string SampleScript =
|
||||||
@"IF (NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'AssessmentResult'))
|
@"IF (NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'AssessmentResult'))
|
||||||
BEGIN
|
BEGIN
|
||||||
CREATE TABLE [dbo].[AssessmentResult](
|
CREATE TABLE [dbo].[AssessmentResult](
|
||||||
[CheckName] [nvarchar](max) NOT NULL,
|
[CheckName] [nvarchar](max),
|
||||||
[CheckId] [nvarchar](max) NOT NULL,
|
[CheckId] [nvarchar](max),
|
||||||
[RulesetName] [nvarchar](max) NOT NULL,
|
[RulesetName] [nvarchar](max),
|
||||||
[RulesetVersion] [nvarchar](max) NOT NULL,
|
[RulesetVersion] [nvarchar](max),
|
||||||
[Severity] [nvarchar](max) NOT NULL,
|
[Severity] [nvarchar](max),
|
||||||
[Message] [nvarchar](max) NOT NULL,
|
[Message] [nvarchar](max),
|
||||||
[TargetPath] [nvarchar](max) NOT NULL,
|
[TargetPath] [nvarchar](max),
|
||||||
[TargetType] [nvarchar](max) NOT NULL,
|
[TargetType] [nvarchar](max),
|
||||||
[HelpLink] [nvarchar](max) NOT NULL,
|
[HelpLink] [nvarchar](max),
|
||||||
[Timestamp] [datetimeoffset](7) NOT NULL
|
[Timestamp] [datetimeoffset](7)
|
||||||
)
|
)
|
||||||
END
|
END
|
||||||
GO
|
GO
|
||||||
INSERT INTO [dbo].[AssessmentResult] ([CheckName],[CheckId],[RulesetName],[RulesetVersion],[Severity],[Message],[TargetPath],[TargetType],[HelpLink],[Timestamp])
|
INSERT INTO [dbo].[AssessmentResult] ([CheckName],[CheckId],[RulesetName],[RulesetVersion],[Severity],[Message],[TargetPath],[TargetType],[HelpLink],[Timestamp])
|
||||||
VALUES
|
SELECT rpt.[CheckName],rpt.[CheckId],rpt.[RulesetName],rpt.[RulesetVersion],rpt.[Severity],rpt.[Message],rpt.[TargetPath],rpt.[TargetType],rpt.[HelpLink],rpt.[Timestamp]
|
||||||
('DN1','C1','Microsoft Ruleset','1.3','Information','Msg''1','proj[*]_dev','Server','HL1','2001-05-25 01:42:00.000 +00:00'),
|
FROM (VALUES
|
||||||
('D N2','C-2','Microsoft Ruleset','1.3','Warning','Msg''1','proj[*]_dev','Database','http://HL2','2001-05-25 01:42:00.000 +03:00'),
|
('DN1','C1','Microsoft Ruleset','1.3','Information','Msg''1','proj[*]_dev','Server','HL1','2001-05-25 01:42:00.000 +00:00'),
|
||||||
('D''N1','C''3','Microsoft Ruleset','1.3','Critical','Msg''1','proj[*]_dev','Server','HL''1','2001-05-25 01:42:00.000 -01:30')";
|
('D N2','C-2','Microsoft Ruleset','1.3','Warning','Msg''1','proj[*]_dev','Database','http://HL2','2001-05-25 01:42:00.000 +03:00'),
|
||||||
|
('D''N1','C''3','Microsoft Ruleset','1.3','Critical','Msg''1','proj[*]_dev','Server','HL''1','2001-05-25 01:42:00.000 -01:30')
|
||||||
[Test]
|
) rpt([CheckName],[CheckId],[RulesetName],[RulesetVersion],[Severity],[Message],[TargetPath],[TargetType],[HelpLink],[Timestamp])";
|
||||||
public void GenerateScriptTest()
|
|
||||||
{
|
[Test]
|
||||||
var scriptText = GenerateScriptOperation.GenerateScript(SampleParams, CancellationToken.None);
|
public void GenerateScriptTest()
|
||||||
Assert.AreEqual(SampleScript, scriptText);
|
{
|
||||||
}
|
var scriptText = GenerateScriptOperation.GenerateScript(SampleParams, CancellationToken.None);
|
||||||
|
Assert.AreEqual(SampleScript, scriptText);
|
||||||
[Test]
|
}
|
||||||
public void ExecuteTest()
|
|
||||||
{
|
[Test]
|
||||||
var subject = new GenerateScriptOperation(SampleParams);
|
public void ExecuteTest()
|
||||||
var taskMetadata = new TaskMetadata();
|
{
|
||||||
using (var sqlTask = new SqlTask(taskMetadata, DummyOpFunction, DummyOpFunction))
|
var subject = new GenerateScriptOperation(SampleParams);
|
||||||
{
|
var taskMetadata = new TaskMetadata();
|
||||||
subject.SqlTask = sqlTask;
|
using (var sqlTask = new SqlTask(taskMetadata, DummyOpFunction, DummyOpFunction))
|
||||||
sqlTask.ScriptAdded += ValidateScriptAdded;
|
{
|
||||||
subject.Execute(TaskExecutionMode.Script);
|
subject.SqlTask = sqlTask;
|
||||||
}
|
sqlTask.ScriptAdded += ValidateScriptAdded;
|
||||||
}
|
subject.Execute(TaskExecutionMode.Script);
|
||||||
|
}
|
||||||
private void ValidateScriptAdded(object sender, TaskEventArgs<TaskScript> e)
|
}
|
||||||
{
|
|
||||||
Assert.AreEqual(SqlTaskStatus.Succeeded, e.TaskData.Status);
|
private void ValidateScriptAdded(object sender, TaskEventArgs<TaskScript> e)
|
||||||
Assert.AreEqual(SampleScript, e.TaskData.Script);
|
{
|
||||||
}
|
Assert.AreEqual(SqlTaskStatus.Succeeded, e.TaskData.Status);
|
||||||
|
Assert.AreEqual(SampleScript, e.TaskData.Script);
|
||||||
private static Task<TaskResult> DummyOpFunction(SqlTask _)
|
}
|
||||||
{
|
|
||||||
return Task.FromResult(new TaskResult() {TaskStatus = SqlTaskStatus.Succeeded});
|
private static Task<TaskResult> DummyOpFunction(SqlTask _)
|
||||||
}
|
{
|
||||||
}
|
return Task.FromResult(new TaskResult() {TaskStatus = SqlTaskStatus.Succeeded});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user