Skip to content

Commit 3acd824

Browse files
committed
integration test
1 parent 3bc6075 commit 3acd824

3 files changed

Lines changed: 131 additions & 0 deletions

File tree

tests/Agent/IntegrationTests/IntegrationTestHelpers/AgentLogBase.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ public abstract class AgentLogBase
8686
public const string WrapperExceptionLogLineRegex = ErrorLogLinePrefixRegex + "An exception occurred in a wrapper";
8787
public const string ApplicationErrorLogLineRegex = DebugLogLinePrefixRegex + "Noticed application error";
8888

89+
// explain plan failure
90+
public const string ExplainPlainFailureLogLineRegex = DebugLogLinePrefixRegex + "Unable to execute explain plan for query: (.*)";
91+
8992
public AgentLogBase(ITestOutputHelper testLogger)
9093
{
9194
_testLogger = testLogger;

tests/Agent/IntegrationTests/SharedApplications/Common/MultiFunctionApplicationHelpers/NetStandardLibraries/MsSql/MicrosoftDataSqlClientExerciser.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using NewRelic.Agent.IntegrationTests.Shared.ReflectionHelpers;
1313
using NewRelic.Api.Agent;
1414
using System.Threading;
15+
using System;
1516

1617
namespace MultiFunctionApplicationHelpers.NetStandardLibraries.MsSql
1718
{
@@ -265,6 +266,63 @@ public void Wait(int millisecondsTimeOut)
265266
Thread.Sleep(millisecondsTimeOut);
266267
}
267268

269+
#if NET9_0
270+
[LibraryMethod]
271+
public async Task MsSqlCreateStoredProcWithTempTable(string procedureName)
272+
{
273+
var createProcedure = $@"
274+
CREATE OR ALTER PROCEDURE {procedureName}
275+
AS
276+
BEGIN
277+
-- Create a temporary table and insert data into it using SELECT INTO
278+
SELECT
279+
Id,
280+
FirstName
281+
INTO #TempTable
282+
FROM
283+
TeamMembers;
284+
285+
-- Select all rows from the temporary table
286+
SELECT * FROM #TempTable;
287+
END;";
288+
289+
await using var connection = new SqlConnection(_connectionString);
290+
await connection.OpenAsync();
291+
292+
await using var command = new SqlCommand(createProcedure, connection);
293+
await command.ExecuteNonQueryAsync();
294+
295+
}
296+
297+
[LibraryMethod]
298+
[Transaction]
299+
[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
300+
public async Task MsSqlStoredProcWithTempTable(string procedureName)
301+
{
302+
await using var connection = new SqlConnection(_connectionString);
303+
await connection.OpenAsync();
304+
305+
await using var command = connection.CreateCommand();
306+
command.CommandText = procedureName;
307+
command.CommandType = System.Data.CommandType.StoredProcedure;
308+
309+
// execute the command
310+
await using var reader = await command.ExecuteReaderAsync();
311+
312+
}
313+
314+
[LibraryMethod]
315+
public async Task MsSqlDropStoredProcWithTempTable(string procedureName)
316+
{
317+
var dropProcedureSql = string.Format(DropProcedureSql, procedureName);
318+
await using var connection = new SqlConnection(_connectionString);
319+
await connection.OpenAsync();
320+
321+
await using var command = new SqlCommand(dropProcedureSql, connection);
322+
await command.ExecuteNonQueryAsync();
323+
}
324+
#endif
325+
268326
private void EnsureProcedure(string procedureName, DbParameter[] dbParameters)
269327
{
270328
var parameters = string.Join(", ", dbParameters.Select(x => $"{x.ParameterName} {x.DbTypeName}"));
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright 2020 New Relic, Inc. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
using Microsoft.VisualStudio.TestPlatform.Utilities;
10+
using NewRelic.Agent.IntegrationTestHelpers;
11+
using NewRelic.Agent.IntegrationTestHelpers.RemoteServiceFixtures;
12+
using Xunit;
13+
using Xunit.Abstractions;
14+
15+
namespace NewRelic.Agent.UnboundedIntegrationTests.MsSql
16+
{
17+
public class MsSqlFailedExplainPlanTests : NewRelicIntegrationTest<ConsoleDynamicMethodFixtureCoreLatest>
18+
{
19+
private readonly ConsoleDynamicMethodFixtureCoreLatest _fixture;
20+
21+
public MsSqlFailedExplainPlanTests(ConsoleDynamicMethodFixtureCoreLatest fixture, ITestOutputHelper outputHelper) : base(fixture)
22+
{
23+
var exerciserName = "MicrosoftDataSqlClientExerciser";
24+
25+
_fixture = fixture;
26+
_fixture.TestLogger = outputHelper;
27+
28+
var procedureName = Utilities.GenerateProcedureName();
29+
30+
_fixture.AddCommand($"{exerciserName} MsSqlCreateStoredProcWithTempTable {procedureName}");
31+
_fixture.AddCommand($"{exerciserName} MsSqlStoredProcWithTempTable {procedureName}");
32+
_fixture.AddCommand($"{exerciserName} MsSqlStoredProcWithTempTable {procedureName}");
33+
_fixture.AddCommand($"{exerciserName} MsSqlDropStoredProcWithTempTable {procedureName}");
34+
35+
_fixture.AddActions
36+
(
37+
setupConfiguration: () =>
38+
{
39+
var configPath = fixture.DestinationNewRelicConfigFilePath;
40+
var configModifier = new NewRelicConfigModifier(configPath);
41+
configModifier.ConfigureFasterMetricsHarvestCycle(15);
42+
configModifier.ConfigureFasterTransactionTracesHarvestCycle(15);
43+
configModifier.ConfigureFasterSqlTracesHarvestCycle(15);
44+
45+
configModifier.ForceTransactionTraces();
46+
configModifier.SetLogLevel("finest"); //This has to stay at finest to ensure parameter check security
47+
48+
CommonUtils.ModifyOrCreateXmlAttributeInNewRelicConfig(configPath, new[] { "configuration", "transactionTracer" }, "explainEnabled", "true");
49+
CommonUtils.ModifyOrCreateXmlAttributeInNewRelicConfig(configPath, new[] { "configuration", "transactionTracer" }, "recordSql", "raw");
50+
CommonUtils.ModifyOrCreateXmlAttributeInNewRelicConfig(configPath, new[] { "configuration", "transactionTracer" }, "explainThreshold", "1");
51+
CommonUtils.ModifyOrCreateXmlAttributeInNewRelicConfig(configPath, new[] { "configuration", "datastoreTracer", "queryParameters" }, "enabled", "true");
52+
},
53+
exerciseApplication: () =>
54+
{
55+
_fixture.AgentLog.WaitForLogLine(AgentLogBase.ExplainPlainFailureLogLineRegex, TimeSpan.FromMinutes(1));
56+
}
57+
);
58+
59+
_fixture.Initialize();
60+
61+
}
62+
63+
[Fact]
64+
public void Test()
65+
{
66+
// verify that the log contains one explain plan failure log line - second call to the stored proc doesn't try to generate an explain plan
67+
Assert.Single(_fixture.AgentLog.TryGetLogLines(AgentLogBase.ExplainPlainFailureLogLineRegex));
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)