From 65383e7376f04fd723bb67a0cff90342c9a0557f Mon Sep 17 00:00:00 2001 From: Maddy Koripalli Date: Wed, 26 Apr 2023 15:49:19 -0700 Subject: [PATCH 1/5] add retry logic --- test/Common/Retry/DelayedMessageBus.cs | 45 ++++++++++++ test/Common/Retry/RetryFactDiscoverer.cs | 30 ++++++++ test/Common/Retry/RetryTestCase.cs | 71 +++++++++++++++++++ .../Common/SupportedLanguagesTestAttribute.cs | 7 ++ 4 files changed, 153 insertions(+) create mode 100644 test/Common/Retry/DelayedMessageBus.cs create mode 100644 test/Common/Retry/RetryFactDiscoverer.cs create mode 100644 test/Common/Retry/RetryTestCase.cs diff --git a/test/Common/Retry/DelayedMessageBus.cs b/test/Common/Retry/DelayedMessageBus.cs new file mode 100644 index 000000000..0bd2f1bd1 --- /dev/null +++ b/test/Common/Retry/DelayedMessageBus.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Xunit.Abstractions; +using Xunit.Sdk; + +namespace Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common +{ + /// + /// Used to capture messages to potentially be forwarded later. Messages are forwarded by + /// disposing of the message bus. + /// + public class DelayedMessageBus : IMessageBus + { + private readonly IMessageBus innerBus; + private readonly List messages = new(); + + public DelayedMessageBus(IMessageBus innerBus) + { + this.innerBus = innerBus; + } + + public bool QueueMessage(IMessageSinkMessage message) + { + lock (this.messages) + { + this.messages.Add(message); + } + + // No way to ask the inner bus if they want to cancel without sending them the message, so + // we just go ahead and continue always. + return true; + } + + public void Dispose() + { + foreach (IMessageSinkMessage message in this.messages) + { + this.innerBus.QueueMessage(message); + } + System.GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/test/Common/Retry/RetryFactDiscoverer.cs b/test/Common/Retry/RetryFactDiscoverer.cs new file mode 100644 index 000000000..a2549e673 --- /dev/null +++ b/test/Common/Retry/RetryFactDiscoverer.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Xunit.Abstractions; +using Xunit.Sdk; + +namespace Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common +{ + public class RetryFactDiscoverer : IXunitTestCaseDiscoverer + { + private readonly IMessageSink diagnosticMessageSink; + + public RetryFactDiscoverer(IMessageSink diagnosticMessageSink) + { + this.diagnosticMessageSink = diagnosticMessageSink; + } + + public IEnumerable Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute) + { + int maxRetries = factAttribute.GetNamedArgument("MaxRetries"); + if (maxRetries < 1) + { + maxRetries = 3; + } + + yield return new RetryTestCase(this.diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod, maxRetries); + } + } +} \ No newline at end of file diff --git a/test/Common/Retry/RetryTestCase.cs b/test/Common/Retry/RetryTestCase.cs new file mode 100644 index 000000000..26b69d850 --- /dev/null +++ b/test/Common/Retry/RetryTestCase.cs @@ -0,0 +1,71 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System; +using System.ComponentModel; +using System.Threading; +using System.Threading.Tasks; +using Xunit.Abstractions; +using Xunit.Sdk; + +namespace Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common +{ + [Serializable] + public class RetryTestCase : XunitTestCase + { + private int maxRetries; + + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")] + public RetryTestCase() { } + + public RetryTestCase(IMessageSink diagnosticMessageSink, TestMethodDisplay testMethodDisplay, TestMethodDisplayOptions defaultMethodDisplayOptions, ITestMethod testMethod, int maxRetries) + : base(diagnosticMessageSink, testMethodDisplay, defaultMethodDisplayOptions, testMethod, testMethodArguments: null) + { + this.maxRetries = maxRetries; + } + + // This method is called by the xUnit test framework classes to run the test case. We will do the + // loop here, forwarding on to the implementation in XunitTestCase to do the heavy lifting. We will + // continue to re-run the test until the aggregator has an error (meaning that some internal error + // condition happened), or the test runs without failure, or we've hit the maximum number of tries. + public override async Task RunAsync(IMessageSink diagnosticMessageSink, + IMessageBus messageBus, + object[] constructorArguments, + ExceptionAggregator aggregator, + CancellationTokenSource cancellationTokenSource) + { + int runCount = 0; + + while (true) + { + // This is really the only tricky bit: we need to capture and delay messages (since those will + // contain run status) until we know we've decided to accept the final result; + var delayedMessageBus = new DelayedMessageBus(messageBus); + + RunSummary summary = await base.RunAsync(diagnosticMessageSink, delayedMessageBus, constructorArguments, aggregator, cancellationTokenSource); + if (aggregator.HasExceptions || summary.Failed == 0 || ++runCount >= this.maxRetries) + { + delayedMessageBus.Dispose(); // Sends all the delayed messages + return summary; + } + + diagnosticMessageSink.OnMessage(new DiagnosticMessage("Execution of '{0}' failed (attempt #{1}), retrying...", "", runCount)); + } + } + + public override void Serialize(IXunitSerializationInfo data) + { + base.Serialize(data); + + data.AddValue("MaxRetries", this.maxRetries); + } + + public override void Deserialize(IXunitSerializationInfo data) + { + base.Deserialize(data); + + this.maxRetries = data.GetValue("MaxRetries"); + } + } +} \ No newline at end of file diff --git a/test/Common/SupportedLanguagesTestAttribute.cs b/test/Common/SupportedLanguagesTestAttribute.cs index 179ecd942..395540908 100644 --- a/test/Common/SupportedLanguagesTestAttribute.cs +++ b/test/Common/SupportedLanguagesTestAttribute.cs @@ -13,10 +13,17 @@ namespace Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common /// tests to be run against all the supported languages list that are specified in the SupportedLanguages /// list of this class /// + [XunitTestCaseDiscoverer("Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common.RetryFactDiscoverer", "Microsoft.Azure.WebJobs.Extensions.Sql.Tests")] public class SqlInlineDataAttribute : DataAttribute { private readonly List testData = new(); + /// + /// Number of retries allowed for a failed test. If unset (or set less than 1), will + /// default to 3 attempts. + /// + public int MaxRetries { get; set; } + /// /// Adds a language parameter to the test data which will contain the language /// that the test is currently running against from the list of supported languages From e48edac752ee9ffb11c952982f9a72a70f91ab9f Mon Sep 17 00:00:00 2001 From: Maddy Koripalli Date: Thu, 27 Apr 2023 10:54:33 -0700 Subject: [PATCH 2/5] fix the csx compilation error --- samples/samples-csx/ProductsTrigger/run.csx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/samples-csx/ProductsTrigger/run.csx b/samples/samples-csx/ProductsTrigger/run.csx index 650e28faf..4a0cb01cf 100644 --- a/samples/samples-csx/ProductsTrigger/run.csx +++ b/samples/samples-csx/ProductsTrigger/run.csx @@ -1,4 +1,4 @@ -#load "../../Common/product.csx" +#load "../Common/product.csx" #r "Newtonsoft.Json" #r "Microsoft.Azure.WebJobs.Extensions.Sql" From 166fb045460c64a7565b029c36af52a6945764a6 Mon Sep 17 00:00:00 2001 From: Maddy Koripalli Date: Fri, 28 Apr 2023 13:19:12 -0700 Subject: [PATCH 3/5] use xRetry --- Directory.Packages.props | 1 + performance/packages.lock.json | 10 +++ samples/samples-outofproc/packages.lock.json | 6 +- test/Common/Retry/DelayedMessageBus.cs | 45 ------------ test/Common/Retry/RetryFactDiscoverer.cs | 30 -------- test/Common/Retry/RetryTestCase.cs | 71 ------------------- .../Common/SupportedLanguagesTestAttribute.cs | 7 -- .../SqlTriggerBindingIntegrationTests.cs | 3 +- ....Azure.WebJobs.Extensions.Sql.Tests.csproj | 1 + test/packages.lock.json | 9 +++ 10 files changed, 26 insertions(+), 157 deletions(-) delete mode 100644 test/Common/Retry/DelayedMessageBus.cs delete mode 100644 test/Common/Retry/RetryFactDiscoverer.cs delete mode 100644 test/Common/Retry/RetryTestCase.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 9064c766e..d1a81fc6d 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -15,6 +15,7 @@ + diff --git a/performance/packages.lock.json b/performance/packages.lock.json index b2526262a..168be8c16 100644 --- a/performance/packages.lock.json +++ b/performance/packages.lock.json @@ -1890,6 +1890,7 @@ "Microsoft.NET.Test.Sdk": "[17.4.0, )", "Moq": "[4.18.2, )", "Newtonsoft.Json": "[13.0.2, )", + "xRetry": "[1.9.0, )", "xunit": "[2.4.2, )", "xunit.runner.visualstudio": "[2.4.5, )" } @@ -2086,6 +2087,15 @@ "System.Configuration.ConfigurationManager": "5.0.0" } }, + "xRetry": { + "type": "CentralTransitive", + "requested": "[1.9.0, )", + "resolved": "1.9.0", + "contentHash": "NeIbJrwpc5EUPagx/mdd/7KzpR36BO8IWrsbgtvOVjxD2xtmNfUHieZ24PeZ4oCYiLBcTviCy+og/bE/OvPchw==", + "dependencies": { + "xunit.core": "[2.4.0, 3.0.0)" + } + }, "xunit": { "type": "CentralTransitive", "requested": "[2.4.2, )", diff --git a/samples/samples-outofproc/packages.lock.json b/samples/samples-outofproc/packages.lock.json index 15d9eb98f..7698d5885 100644 --- a/samples/samples-outofproc/packages.lock.json +++ b/samples/samples-outofproc/packages.lock.json @@ -846,9 +846,9 @@ "microsoft.azure.functions.worker.extensions.sql": { "type": "Project", "dependencies": { - "Microsoft.Azure.Functions.Worker.Extensions.Abstractions": "1.1.0", - "Microsoft.Data.SqlClient": "5.0.1", - "System.Drawing.Common": "5.0.3" + "Microsoft.Azure.Functions.Worker.Extensions.Abstractions": "[1.1.0, )", + "Microsoft.Data.SqlClient": "[5.0.1, )", + "System.Drawing.Common": "[5.0.3, )" } }, "Microsoft.Azure.Functions.Worker.Extensions.Abstractions": { diff --git a/test/Common/Retry/DelayedMessageBus.cs b/test/Common/Retry/DelayedMessageBus.cs deleted file mode 100644 index 0bd2f1bd1..000000000 --- a/test/Common/Retry/DelayedMessageBus.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. - -using System.Collections.Generic; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common -{ - /// - /// Used to capture messages to potentially be forwarded later. Messages are forwarded by - /// disposing of the message bus. - /// - public class DelayedMessageBus : IMessageBus - { - private readonly IMessageBus innerBus; - private readonly List messages = new(); - - public DelayedMessageBus(IMessageBus innerBus) - { - this.innerBus = innerBus; - } - - public bool QueueMessage(IMessageSinkMessage message) - { - lock (this.messages) - { - this.messages.Add(message); - } - - // No way to ask the inner bus if they want to cancel without sending them the message, so - // we just go ahead and continue always. - return true; - } - - public void Dispose() - { - foreach (IMessageSinkMessage message in this.messages) - { - this.innerBus.QueueMessage(message); - } - System.GC.SuppressFinalize(this); - } - } -} \ No newline at end of file diff --git a/test/Common/Retry/RetryFactDiscoverer.cs b/test/Common/Retry/RetryFactDiscoverer.cs deleted file mode 100644 index a2549e673..000000000 --- a/test/Common/Retry/RetryFactDiscoverer.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. - -using System.Collections.Generic; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common -{ - public class RetryFactDiscoverer : IXunitTestCaseDiscoverer - { - private readonly IMessageSink diagnosticMessageSink; - - public RetryFactDiscoverer(IMessageSink diagnosticMessageSink) - { - this.diagnosticMessageSink = diagnosticMessageSink; - } - - public IEnumerable Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute) - { - int maxRetries = factAttribute.GetNamedArgument("MaxRetries"); - if (maxRetries < 1) - { - maxRetries = 3; - } - - yield return new RetryTestCase(this.diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod, maxRetries); - } - } -} \ No newline at end of file diff --git a/test/Common/Retry/RetryTestCase.cs b/test/Common/Retry/RetryTestCase.cs deleted file mode 100644 index 26b69d850..000000000 --- a/test/Common/Retry/RetryTestCase.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. - -using System; -using System.ComponentModel; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common -{ - [Serializable] - public class RetryTestCase : XunitTestCase - { - private int maxRetries; - - [EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")] - public RetryTestCase() { } - - public RetryTestCase(IMessageSink diagnosticMessageSink, TestMethodDisplay testMethodDisplay, TestMethodDisplayOptions defaultMethodDisplayOptions, ITestMethod testMethod, int maxRetries) - : base(diagnosticMessageSink, testMethodDisplay, defaultMethodDisplayOptions, testMethod, testMethodArguments: null) - { - this.maxRetries = maxRetries; - } - - // This method is called by the xUnit test framework classes to run the test case. We will do the - // loop here, forwarding on to the implementation in XunitTestCase to do the heavy lifting. We will - // continue to re-run the test until the aggregator has an error (meaning that some internal error - // condition happened), or the test runs without failure, or we've hit the maximum number of tries. - public override async Task RunAsync(IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - object[] constructorArguments, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - { - int runCount = 0; - - while (true) - { - // This is really the only tricky bit: we need to capture and delay messages (since those will - // contain run status) until we know we've decided to accept the final result; - var delayedMessageBus = new DelayedMessageBus(messageBus); - - RunSummary summary = await base.RunAsync(diagnosticMessageSink, delayedMessageBus, constructorArguments, aggregator, cancellationTokenSource); - if (aggregator.HasExceptions || summary.Failed == 0 || ++runCount >= this.maxRetries) - { - delayedMessageBus.Dispose(); // Sends all the delayed messages - return summary; - } - - diagnosticMessageSink.OnMessage(new DiagnosticMessage("Execution of '{0}' failed (attempt #{1}), retrying...", "", runCount)); - } - } - - public override void Serialize(IXunitSerializationInfo data) - { - base.Serialize(data); - - data.AddValue("MaxRetries", this.maxRetries); - } - - public override void Deserialize(IXunitSerializationInfo data) - { - base.Deserialize(data); - - this.maxRetries = data.GetValue("MaxRetries"); - } - } -} \ No newline at end of file diff --git a/test/Common/SupportedLanguagesTestAttribute.cs b/test/Common/SupportedLanguagesTestAttribute.cs index 395540908..179ecd942 100644 --- a/test/Common/SupportedLanguagesTestAttribute.cs +++ b/test/Common/SupportedLanguagesTestAttribute.cs @@ -13,17 +13,10 @@ namespace Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common /// tests to be run against all the supported languages list that are specified in the SupportedLanguages /// list of this class /// - [XunitTestCaseDiscoverer("Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common.RetryFactDiscoverer", "Microsoft.Azure.WebJobs.Extensions.Sql.Tests")] public class SqlInlineDataAttribute : DataAttribute { private readonly List testData = new(); - /// - /// Number of retries allowed for a failed test. If unset (or set less than 1), will - /// default to 3 attempts. - /// - public int MaxRetries { get; set; } - /// /// Adds a language parameter to the test data which will contain the language /// that the test is currently running against from the list of supported languages diff --git a/test/Integration/SqlTriggerBindingIntegrationTests.cs b/test/Integration/SqlTriggerBindingIntegrationTests.cs index f0a3e1143..dcaefa992 100644 --- a/test/Integration/SqlTriggerBindingIntegrationTests.cs +++ b/test/Integration/SqlTriggerBindingIntegrationTests.cs @@ -15,6 +15,7 @@ using Moq; using Xunit; using Xunit.Abstractions; +using xRetry; namespace Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Integration { @@ -28,7 +29,7 @@ public SqlTriggerBindingIntegrationTests(ITestOutputHelper output = null) : base /// /// Ensures that the user function gets invoked for each of the insert, update and delete operation. /// - [Theory] + [RetryTheory] [SqlInlineData()] public async Task SingleOperationTriggerTest(SupportedLanguages lang) { diff --git a/test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj b/test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj index ef533f160..dbed0a782 100644 --- a/test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj +++ b/test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj @@ -5,6 +5,7 @@ + diff --git a/test/packages.lock.json b/test/packages.lock.json index 492b16351..5eda640be 100644 --- a/test/packages.lock.json +++ b/test/packages.lock.json @@ -74,6 +74,15 @@ "resolved": "13.0.2", "contentHash": "R2pZ3B0UjeyHShm9vG+Tu0EBb2lC8b0dFzV9gVn50ofHXh9Smjk6kTn7A/FdAsC8B5cKib1OnGYOXxRBz5XQDg==" }, + "xRetry": { + "type": "Direct", + "requested": "[1.9.0, )", + "resolved": "1.9.0", + "contentHash": "NeIbJrwpc5EUPagx/mdd/7KzpR36BO8IWrsbgtvOVjxD2xtmNfUHieZ24PeZ4oCYiLBcTviCy+og/bE/OvPchw==", + "dependencies": { + "xunit.core": "[2.4.0, 3.0.0)" + } + }, "xunit": { "type": "Direct", "requested": "[2.4.2, )", From a174aa561e013b782c5f9be11a605da93bd6be57 Mon Sep 17 00:00:00 2001 From: Maddy Koripalli Date: Fri, 28 Apr 2023 13:21:58 -0700 Subject: [PATCH 4/5] replace with RetryTheory --- .../SqlTriggerBindingIntegrationTests.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/Integration/SqlTriggerBindingIntegrationTests.cs b/test/Integration/SqlTriggerBindingIntegrationTests.cs index dcaefa992..92646f3fd 100644 --- a/test/Integration/SqlTriggerBindingIntegrationTests.cs +++ b/test/Integration/SqlTriggerBindingIntegrationTests.cs @@ -77,7 +77,7 @@ await this.WaitForProductChanges( /// Verifies that manually setting the batch size using the original config var correctly changes the /// number of changes processed at once. /// - [Theory] + [RetryTheory] [SqlInlineData()] public async Task BatchSizeOverrideTriggerTest(SupportedLanguages lang) { @@ -120,7 +120,7 @@ await this.WaitForProductChanges( /// /// Verifies that manually setting the max batch size correctly changes the number of changes processed at once /// - [Theory] + [RetryTheory] [SqlInlineData()] public async Task MaxBatchSizeOverrideTriggerTest(SupportedLanguages lang) { @@ -163,7 +163,7 @@ await this.WaitForProductChanges( /// /// Verifies that manually setting the polling interval correctly changes the delay between processing each batch of changes /// - [Theory] + [RetryTheory] [SqlInlineData()] public async Task PollingIntervalOverrideTriggerTest(SupportedLanguages lang) { @@ -205,7 +205,7 @@ await this.WaitForProductChanges( /// Verifies that if several changes have happened to the table row since last invocation, then a single net /// change for that row is passed to the user function. /// - [Theory] + [RetryTheory] [SqlInlineData()] public async Task MultiOperationTriggerTest(SupportedLanguages lang) { @@ -286,7 +286,7 @@ await this.WaitForProductChanges( /// /// Ensures correct functionality with multiple user functions tracking the same table. /// - [Theory] + [RetryTheory] [SqlInlineData()] public async Task MultiFunctionTriggerTest(SupportedLanguages lang) { @@ -412,7 +412,7 @@ public async Task MultiFunctionTriggerTest(SupportedLanguages lang) /// /// Ensures correct functionality with user functions running across multiple functions host processes. /// - [Theory] + [RetryTheory] [SqlInlineData()] public async Task MultiHostTriggerTest(SupportedLanguages lang) { @@ -463,7 +463,7 @@ await this.WaitForProductChanges( /// /// Tests the error message when the user table is not present in the database. /// - [Theory] + [RetryTheory] [SqlInlineData()] public void TableNotPresentTriggerTest(SupportedLanguages lang) { @@ -477,7 +477,7 @@ public void TableNotPresentTriggerTest(SupportedLanguages lang) /// /// Tests the error message when the user table does not contain primary key. /// - [Theory] + [RetryTheory] [SqlInlineData()] public void PrimaryKeyNotCreatedTriggerTest(SupportedLanguages lang) { @@ -492,7 +492,7 @@ public void PrimaryKeyNotCreatedTriggerTest(SupportedLanguages lang) /// Tests the error message when the user table contains one or more primary keys with names conflicting with /// column names in the leases table. /// - [Theory] + [RetryTheory] [SqlInlineData()] public void ReservedPrimaryKeyColumnNamesTriggerTest(SupportedLanguages lang) { @@ -507,7 +507,7 @@ public void ReservedPrimaryKeyColumnNamesTriggerTest(SupportedLanguages lang) /// /// Tests the error message when the user table contains columns of unsupported SQL types. /// - [Theory] + [RetryTheory] [SqlInlineData()] public void UnsupportedColumnTypesTriggerTest(SupportedLanguages lang) { @@ -522,7 +522,7 @@ public void UnsupportedColumnTypesTriggerTest(SupportedLanguages lang) /// /// Tests the error message when change tracking is not enabled on the user table. /// - [Theory] + [RetryTheory] [SqlInlineData()] public void ChangeTrackingNotEnabledTriggerTest(SupportedLanguages lang) { @@ -558,7 +558,7 @@ public async void GetMetricsTest() /// /// Tests that when using an unsupported database the expected error is thrown /// - [Theory] + [RetryTheory] [SqlInlineData()] public void UnsupportedDatabaseThrows(SupportedLanguages lang) { From 5fc459d0c93982575763e5e0e0e55a64014bd8bc Mon Sep 17 00:00:00 2001 From: Maddy Koripalli Date: Mon, 1 May 2023 13:18:26 -0700 Subject: [PATCH 5/5] add diagnostic messages to logs --- Directory.Packages.props | 2 +- test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj | 7 +++++-- test/xunit.runner.json | 4 ++++ 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 test/xunit.runner.json diff --git a/Directory.Packages.props b/Directory.Packages.props index d1a81fc6d..e0dd5cf0d 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -15,7 +15,7 @@ - + diff --git a/test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj b/test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj index dbed0a782..7dddc6de3 100644 --- a/test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj +++ b/test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj @@ -19,8 +19,11 @@ - Always - + Always + + + PreserveNewest + diff --git a/test/xunit.runner.json b/test/xunit.runner.json new file mode 100644 index 000000000..af6c85ea4 --- /dev/null +++ b/test/xunit.runner.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "diagnosticMessages": true +} \ No newline at end of file