mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 17:23:27 -05:00
* Checkpoint * Checkpoint * Checkpoint * checkpoint * Hooking in calls to QueryExecutionService * adding cases * Fleshing out report handlers * Adding parameter converters * Adding sqlparam declarations for Top Resource Consumers and Forced Plans * swapping to object-object to centralize conversion for sqlparams * Adding sqlparams for GetTrackedQueries * Added sqlparams for High Variation * Added Overall ResourceConumption * Adding params for regressed queries * Removing WithWaitStats calls, since they're automatically used within QSM when waitstats is an available statistic# * Adding PlanSummary handlers * cleaning up orderable queries * initial test mockout * adding basic (incorrect) parameter translation * first test passing, datetimeoffset swapped to ISO format * Adding test baselines * Updating nuget package * Adding get/set * Adding get/set for result object * Switching to parameter-less constructor * Swapping TimeInterval for string-based BasicTimeInterval * Removing unnecessary usings * Adding back params comments * Fixing up request docstrings * comment tweak * fix tests failing in pipeline because of line endings not matching * removing unnecessary usings * Setting tests to generate queries in UTC for test stability * Normalizing line endings --------- Co-authored-by: Kim Santiago <kisantia@microsoft.com>
285 lines
13 KiB
C#
285 lines
13 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.Threading.Tasks;
|
|
using Microsoft.SqlServer.Management.QueryStoreModel.Common;
|
|
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
|
|
using Microsoft.SqlTools.ServiceLayer.QueryStore;
|
|
using Microsoft.SqlTools.ServiceLayer.QueryStore.Contracts;
|
|
using Microsoft.SqlTools.ServiceLayer.Test.Common.RequestContextMocking;
|
|
using Moq;
|
|
using NUnit.Framework;
|
|
using static Microsoft.SqlServer.Management.QueryStoreModel.PlanSummary.PlanSummaryConfiguration;
|
|
|
|
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.QueryStore
|
|
{
|
|
public class QueryStoreTests : TestBase
|
|
{
|
|
private const string TestConnectionOwnerUri = "FakeConnectionOwnerUri";
|
|
private static DateTimeOffset TestWindowStart = DateTimeOffset.Parse("6/10/2023 12:34:56 PM +0:00");
|
|
private static DateTimeOffset TestWindowEnd = TestWindowStart.AddDays(7);
|
|
private static DateTimeOffset TestWindowRecentStart = TestWindowEnd.AddHours(-1);
|
|
private static BasicTimeInterval TestTimeInterval => new BasicTimeInterval()
|
|
{
|
|
StartDateTimeInUtc = TestWindowStart.ToString("O"),
|
|
EndDateTimeInUtc = TestWindowEnd.ToString("O")
|
|
};
|
|
|
|
private static BasicTimeInterval RecentTestTimeInterval => new BasicTimeInterval()
|
|
{
|
|
StartDateTimeInUtc = TestWindowRecentStart.ToString("O"),
|
|
EndDateTimeInUtc = TestWindowEnd.ToString("O")
|
|
};
|
|
|
|
[SetUp]
|
|
public void Setup()
|
|
{
|
|
QueryStoreCommonConfiguration.DisplayTimeKind = DateTimeKind.Utc;
|
|
}
|
|
|
|
[Test]
|
|
public async Task TopResourceConsumers()
|
|
{
|
|
QueryStoreService service = GetMock();
|
|
|
|
MockRequest<QueryStoreQueryResult> request = new();
|
|
await service.HandleGetTopResourceConsumersSummaryReportRequest(new GetTopResourceConsumersReportParams()
|
|
{
|
|
ConnectionOwnerUri = TestConnectionOwnerUri,
|
|
ReturnAllQueries = true,
|
|
SelectedMetric = Metric.WaitTime,
|
|
SelectedStatistic = Statistic.Stdev,
|
|
OrderByColumnId = "query_id",
|
|
Descending = true,
|
|
MinNumberOfQueryPlans = 1,
|
|
TopQueriesReturned = 50,
|
|
TimeInterval = TestTimeInterval
|
|
}, request.Object);
|
|
|
|
request.AssertSuccess(nameof(service.HandleGetTopResourceConsumersSummaryReportRequest));
|
|
Assert.AreEqual(QueryStoreBaselines.HandleGetTopResourceConsumersSummaryReportRequest.ReplaceLineEndings(), request.Result.Query.ReplaceLineEndings());
|
|
|
|
request = new();
|
|
await service.HandleGetTopResourceConsumersDetailedSummaryReportRequest(new GetTopResourceConsumersReportParams()
|
|
{
|
|
ConnectionOwnerUri = TestConnectionOwnerUri,
|
|
ReturnAllQueries = true,
|
|
SelectedMetric = Metric.WaitTime,
|
|
SelectedStatistic = Statistic.Stdev,
|
|
OrderByColumnId = "query_id",
|
|
Descending = true,
|
|
MinNumberOfQueryPlans = 1,
|
|
TopQueriesReturned = 50,
|
|
TimeInterval = TestTimeInterval
|
|
}, request.Object);
|
|
|
|
request.AssertSuccess(nameof(service.HandleGetTopResourceConsumersDetailedSummaryReportRequest));
|
|
Assert.AreEqual(QueryStoreBaselines.HandleGetTopResourceConsumersDetailedSummaryReportRequest.ReplaceLineEndings(), request.Result.Query.ReplaceLineEndings());
|
|
}
|
|
|
|
[Test]
|
|
public async Task ForcedPlanQueries()
|
|
{
|
|
QueryStoreService service = GetMock();
|
|
|
|
MockRequest<QueryStoreQueryResult> request = new();
|
|
await service.HandleGetForcedPlanQueriesReportRequest(new GetForcedPlanQueriesReportParams()
|
|
{
|
|
ConnectionOwnerUri = TestConnectionOwnerUri,
|
|
ReturnAllQueries = true,
|
|
SelectedMetric = Metric.WaitTime,
|
|
SelectedStatistic = Statistic.Stdev,
|
|
OrderByColumnId = "query_id",
|
|
Descending = true,
|
|
MinNumberOfQueryPlans = 1,
|
|
TopQueriesReturned = 50,
|
|
TimeInterval = TestTimeInterval
|
|
}, request.Object);
|
|
|
|
request.AssertSuccess(nameof(service.HandleGetForcedPlanQueriesReportRequest));
|
|
Assert.AreEqual(QueryStoreBaselines.HandleGetForcedPlanQueriesReportRequest.ReplaceLineEndings(), request.Result.Query.ReplaceLineEndings());
|
|
}
|
|
|
|
[Test]
|
|
public async Task TrackedQueries()
|
|
{
|
|
QueryStoreService service = GetMock();
|
|
|
|
MockRequest<QueryStoreQueryResult> request = new();
|
|
await service.HandleGetTrackedQueriesReportRequest(new GetTrackedQueriesReportParams()
|
|
{
|
|
QuerySearchText = "test search text"
|
|
}, request.Object);
|
|
|
|
request.AssertSuccess(nameof(service.HandleGetTrackedQueriesReportRequest));
|
|
Assert.AreEqual(QueryStoreBaselines.HandleGetTrackedQueriesReportRequest.ReplaceLineEndings(), request.Result.Query.ReplaceLineEndings());
|
|
}
|
|
|
|
[Test]
|
|
public async Task HighVariationQueries()
|
|
{
|
|
QueryStoreService service = GetMock();
|
|
|
|
MockRequest<QueryStoreQueryResult> request = new();
|
|
await service.HandleGetHighVariationQueriesSummaryReportRequest(new GetHighVariationQueriesReportParams()
|
|
{
|
|
ConnectionOwnerUri = TestConnectionOwnerUri,
|
|
ReturnAllQueries = true,
|
|
SelectedMetric = Metric.WaitTime,
|
|
SelectedStatistic = Statistic.Stdev,
|
|
OrderByColumnId = "query_id",
|
|
Descending = true,
|
|
MinNumberOfQueryPlans = 1,
|
|
TopQueriesReturned = 50,
|
|
TimeInterval = TestTimeInterval
|
|
}, request.Object);
|
|
|
|
request.AssertSuccess(nameof(service.HandleGetHighVariationQueriesSummaryReportRequest));
|
|
Assert.AreEqual(QueryStoreBaselines.HandleGetHighVariationQueriesSummaryReportRequest.ReplaceLineEndings(), request.Result.Query.ReplaceLineEndings());
|
|
|
|
request = new();
|
|
await service.HandleGetHighVariationQueriesDetailedSummaryReportRequest(new GetHighVariationQueriesReportParams()
|
|
{
|
|
ConnectionOwnerUri = TestConnectionOwnerUri,
|
|
ReturnAllQueries = true,
|
|
SelectedMetric = Metric.WaitTime,
|
|
SelectedStatistic = Statistic.Stdev,
|
|
OrderByColumnId = "query_id",
|
|
Descending = true,
|
|
MinNumberOfQueryPlans = 1,
|
|
TopQueriesReturned = 50,
|
|
TimeInterval = TestTimeInterval
|
|
}, request.Object);
|
|
|
|
request.AssertSuccess(nameof(service.HandleGetHighVariationQueriesDetailedSummaryReportRequest));
|
|
Assert.AreEqual(QueryStoreBaselines.HandleGetHighVariationQueriesDetailedSummaryReportRequest.ReplaceLineEndings(), request.Result.Query.ReplaceLineEndings());
|
|
}
|
|
|
|
[Test]
|
|
public async Task OverallResourceConsumption()
|
|
{
|
|
QueryStoreService service = GetMock();
|
|
|
|
MockRequest<QueryStoreQueryResult> request = new();
|
|
await service.HandleGetOverallResourceConsumptionReportRequest(new GetOverallResourceConsumptionReportParams()
|
|
{
|
|
ConnectionOwnerUri = TestConnectionOwnerUri,
|
|
ReturnAllQueries = true,
|
|
SelectedMetric = Metric.WaitTime,
|
|
SelectedStatistic = Statistic.Stdev,
|
|
MinNumberOfQueryPlans = 1,
|
|
TopQueriesReturned = 50,
|
|
SpecifiedTimeInterval = TestTimeInterval,
|
|
SpecifiedBucketInterval = BucketInterval.Hour
|
|
}, request.Object);
|
|
|
|
request.AssertSuccess(nameof(service.HandleGetOverallResourceConsumptionReportRequest));
|
|
Assert.AreEqual(QueryStoreBaselines.HandleGetOverallResourceConsumptionReportRequest.ReplaceLineEndings(), request.Result.Query.ReplaceLineEndings());
|
|
}
|
|
|
|
[Test]
|
|
public async Task RegressedQueries()
|
|
{
|
|
QueryStoreService service = GetMock();
|
|
|
|
MockRequest<QueryStoreQueryResult> request = new();
|
|
await service.HandleGetRegressedQueriesSummaryReportRequest(new GetRegressedQueriesReportParams()
|
|
{
|
|
ConnectionOwnerUri = TestConnectionOwnerUri,
|
|
ReturnAllQueries = true,
|
|
SelectedMetric = Metric.WaitTime,
|
|
SelectedStatistic = Statistic.Stdev,
|
|
MinNumberOfQueryPlans = 1,
|
|
TopQueriesReturned = 50,
|
|
MinExecutionCount = 1,
|
|
TimeIntervalHistory = TestTimeInterval,
|
|
TimeIntervalRecent = RecentTestTimeInterval
|
|
}, request.Object);
|
|
|
|
request.AssertSuccess(nameof(service.HandleGetRegressedQueriesSummaryReportRequest));
|
|
Assert.AreEqual(QueryStoreBaselines.HandleGetRegressedQueriesSummaryReportRequest.ReplaceLineEndings(), request.Result.Query.ReplaceLineEndings());
|
|
|
|
request = new();
|
|
await service.HandleGetRegressedQueriesDetailedSummaryReportRequest(new GetRegressedQueriesReportParams()
|
|
{
|
|
ConnectionOwnerUri = TestConnectionOwnerUri,
|
|
ReturnAllQueries = true,
|
|
SelectedMetric = Metric.WaitTime,
|
|
SelectedStatistic = Statistic.Stdev,
|
|
MinNumberOfQueryPlans = 1,
|
|
TopQueriesReturned = 50,
|
|
MinExecutionCount = 1,
|
|
TimeIntervalHistory = TestTimeInterval,
|
|
TimeIntervalRecent = RecentTestTimeInterval
|
|
}, request.Object);
|
|
|
|
request.AssertSuccess(nameof(service.HandleGetRegressedQueriesDetailedSummaryReportRequest));
|
|
Assert.AreEqual(QueryStoreBaselines.HandleGetRegressedQueriesDetailedSummaryReportRequest.ReplaceLineEndings(), request.Result.Query.ReplaceLineEndings());
|
|
}
|
|
|
|
[Test]
|
|
public async Task PlanSummary()
|
|
{
|
|
QueryStoreService service = GetMock();
|
|
|
|
MockRequest<QueryStoreQueryResult> request = new();
|
|
await service.HandleGetPlanSummaryChartViewRequest(new GetPlanSummaryParams()
|
|
{
|
|
ConnectionOwnerUri = TestConnectionOwnerUri,
|
|
QueryId = 97,
|
|
TimeInterval = TestTimeInterval,
|
|
TimeIntervalMode = PlanTimeIntervalMode.SpecifiedRange,
|
|
SelectedMetric = Metric.WaitTime,
|
|
SelectedStatistic = Statistic.Stdev
|
|
}, request.Object);
|
|
|
|
request.AssertSuccess(nameof(service.HandleGetPlanSummaryChartViewRequest));
|
|
Assert.AreEqual(QueryStoreBaselines.HandleGetPlanSummaryChartViewRequest.ReplaceLineEndings(), request.Result.Query.ReplaceLineEndings());
|
|
|
|
request = new();
|
|
await service.HandleGetPlanSummaryGridViewRequest(new GetPlanSummaryGridViewParams()
|
|
{
|
|
ConnectionOwnerUri = TestConnectionOwnerUri,
|
|
QueryId = 97,
|
|
TimeInterval = TestTimeInterval,
|
|
TimeIntervalMode = PlanTimeIntervalMode.SpecifiedRange,
|
|
SelectedMetric = Metric.WaitTime,
|
|
SelectedStatistic = Statistic.Stdev,
|
|
OrderByColumnId = "count_executions",
|
|
Descending = true
|
|
}, request.Object);
|
|
|
|
request.AssertSuccess(nameof(service.HandleGetPlanSummaryGridViewRequest));
|
|
Assert.AreEqual(QueryStoreBaselines.HandleGetPlanSummaryGridViewRequest.ReplaceLineEndings(), request.Result.Query.ReplaceLineEndings());
|
|
}
|
|
|
|
private QueryStoreService GetMock()
|
|
{
|
|
Mock<QueryStoreService> mock = new Mock<QueryStoreService>();
|
|
mock.Setup(s => s.GetAvailableMetrics(It.IsAny<QueryStoreReportParams>()))
|
|
.Returns(new List<Metric>()
|
|
{
|
|
Metric.ClrTime,
|
|
Metric.CPUTime,
|
|
Metric.Dop,
|
|
Metric.Duration,
|
|
Metric.ExecutionCount,
|
|
Metric.LogicalReads,
|
|
Metric.LogicalWrites,
|
|
Metric.LogMemoryUsed,
|
|
Metric.MemoryConsumption,
|
|
Metric.PhysicalReads,
|
|
Metric.RowCount,
|
|
Metric.TempDbMemoryUsed,
|
|
Metric.WaitTime
|
|
});
|
|
|
|
return mock.Object;
|
|
}
|
|
}
|
|
}
|