From 164aef7ab32a70a326f6450469115343a241d197 Mon Sep 17 00:00:00 2001 From: Maddy Koripalli Date: Fri, 14 Apr 2023 11:31:39 -0700 Subject: [PATCH 1/7] add trigger samples for csx --- .../.vscode/extensions.json | 5 ++ .../ProductsTrigger/function.json | 12 ++++ .../ProductsTrigger/run.csx | 14 ++++ .../TriggerBindingSamples/host.json | 15 ++++ test/Integration/test-csx/Common/Product.csx | 70 +++++++++++++++++++ .../MultiFunctionTrigger1/function.json | 12 ++++ .../test-csx/MultiFunctionTrigger1/run.csx | 14 ++++ .../MultiFunctionTrigger2/function.json | 12 ++++ .../test-csx/MultiFunctionTrigger2/run.csx | 14 ++++ .../PrimaryKeyNotPresentTrigger/function.json | 12 ++++ .../PrimaryKeyNotPresentTrigger/run.csx | 14 ++++ .../function.json | 12 ++++ .../ProductsTriggerWithValidation/run.csx | 20 ++++++ .../function.json | 12 ++++ .../run.csx | 12 ++++ .../TableNotPresentTrigger/function.json | 12 ++++ .../test-csx/TableNotPresentTrigger/run.csx | 12 ++++ .../function.json | 12 ++++ .../UnsupportedColumnTypesTrigger/run.csx | 12 ++++ 19 files changed, 298 insertions(+) create mode 100644 samples/samples-csharpscript/TriggerBindingSamples/.vscode/extensions.json create mode 100644 samples/samples-csharpscript/TriggerBindingSamples/ProductsTrigger/function.json create mode 100644 samples/samples-csharpscript/TriggerBindingSamples/ProductsTrigger/run.csx create mode 100644 samples/samples-csharpscript/TriggerBindingSamples/host.json create mode 100644 test/Integration/test-csx/MultiFunctionTrigger1/function.json create mode 100644 test/Integration/test-csx/MultiFunctionTrigger1/run.csx create mode 100644 test/Integration/test-csx/MultiFunctionTrigger2/function.json create mode 100644 test/Integration/test-csx/MultiFunctionTrigger2/run.csx create mode 100644 test/Integration/test-csx/PrimaryKeyNotPresentTrigger/function.json create mode 100644 test/Integration/test-csx/PrimaryKeyNotPresentTrigger/run.csx create mode 100644 test/Integration/test-csx/ProductsTriggerWithValidation/function.json create mode 100644 test/Integration/test-csx/ProductsTriggerWithValidation/run.csx create mode 100644 test/Integration/test-csx/ReservedPrimaryKeyColumnNamesTrigger/function.json create mode 100644 test/Integration/test-csx/ReservedPrimaryKeyColumnNamesTrigger/run.csx create mode 100644 test/Integration/test-csx/TableNotPresentTrigger/function.json create mode 100644 test/Integration/test-csx/TableNotPresentTrigger/run.csx create mode 100644 test/Integration/test-csx/UnsupportedColumnTypesTrigger/function.json create mode 100644 test/Integration/test-csx/UnsupportedColumnTypesTrigger/run.csx diff --git a/samples/samples-csharpscript/TriggerBindingSamples/.vscode/extensions.json b/samples/samples-csharpscript/TriggerBindingSamples/.vscode/extensions.json new file mode 100644 index 000000000..dde673dcd --- /dev/null +++ b/samples/samples-csharpscript/TriggerBindingSamples/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "ms-azuretools.vscode-azurefunctions" + ] +} \ No newline at end of file diff --git a/samples/samples-csharpscript/TriggerBindingSamples/ProductsTrigger/function.json b/samples/samples-csharpscript/TriggerBindingSamples/ProductsTrigger/function.json new file mode 100644 index 000000000..f52bcac4c --- /dev/null +++ b/samples/samples-csharpscript/TriggerBindingSamples/ProductsTrigger/function.json @@ -0,0 +1,12 @@ +{ + "bindings": [ + { + "name": "changes", + "type": "sqlTrigger", + "direction": "in", + "tableName": "dbo.Products", + "connectionStringSetting": "SqlConnectionString" + } + ], + "disabled": false +} \ No newline at end of file diff --git a/samples/samples-csharpscript/TriggerBindingSamples/ProductsTrigger/run.csx b/samples/samples-csharpscript/TriggerBindingSamples/ProductsTrigger/run.csx new file mode 100644 index 000000000..650e28faf --- /dev/null +++ b/samples/samples-csharpscript/TriggerBindingSamples/ProductsTrigger/run.csx @@ -0,0 +1,14 @@ +#load "../../Common/product.csx" +#r "Newtonsoft.Json" +#r "Microsoft.Azure.WebJobs.Extensions.Sql" + +using System.Net; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Primitives; +using Newtonsoft.Json; +using Microsoft.Azure.WebJobs.Extensions.Sql; + +public static void Run(IReadOnlyList> changes, ILogger log) +{ + log.LogInformation("SQL Changes: " + JsonConvert.SerializeObject(changes)); +} \ No newline at end of file diff --git a/samples/samples-csharpscript/TriggerBindingSamples/host.json b/samples/samples-csharpscript/TriggerBindingSamples/host.json new file mode 100644 index 000000000..22c599f81 --- /dev/null +++ b/samples/samples-csharpscript/TriggerBindingSamples/host.json @@ -0,0 +1,15 @@ +{ + "version": "2.0", + "logging": { + "applicationInsights": { + "samplingSettings": { + "isEnabled": true, + "excludedTypes": "Request" + } + } + }, + "extensionBundle": { + "id": "Microsoft.Azure.Functions.ExtensionBundle.Preview", + "version": "[4.*, 5.0.0)" + } +} \ No newline at end of file diff --git a/test/Integration/test-csx/Common/Product.csx b/test/Integration/test-csx/Common/Product.csx index 5ef26794d..bbc9247b3 100644 --- a/test/Integration/test-csx/Common/Product.csx +++ b/test/Integration/test-csx/Common/Product.csx @@ -1,8 +1,16 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. +#r "Newtonsoft.Json" + using System; using System.Linq; +using System.IO; +using System.Text; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; public class Product { @@ -234,4 +242,66 @@ public class ProductUtilities } return products; } +} + +public static class Utils +{ + /// + /// Default JSON serializer settings to use + /// + private static readonly JsonSerializerSettings _defaultJsonSerializationSettings; + + static Utils() + { + _defaultJsonSerializationSettings = new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver() + }; + } + + /// + /// Serializes the specified object into a JSON string. + /// + /// The object to serialize + /// The specific settings to use, uses a simple set of default settings if not specified + /// The serialized JSON string + /// This will NOT use any global settings to avoid picking up changes that may have been made by other code running in the host (such as user functions) + public static string JsonSerializeObject(object obj, JsonSerializerSettings settings = null) + { + settings = settings ?? _defaultJsonSerializationSettings; + // Following the Newtonsoft implementation in JsonConvert of creating a new JsonSerializer each time. + // https://github.com/JamesNK/Newtonsoft.Json/blob/57025815e564d36821acf778e2c00d02225aab35/Src/Newtonsoft.Json/JsonConvert.cs#L612 + // If performance ends up being an issue could look into creating a single instance of the serializer for each setting. + var serializer = JsonSerializer.Create(settings); + // 256 is value used by Newtonsoft by default - helps avoid having to expand it too many times for larger strings + // https://github.com/JamesNK/Newtonsoft.Json/blob/57025815e564d36821acf778e2c00d02225aab35/Src/Newtonsoft.Json/JsonConvert.cs#L659 + var sb = new StringBuilder(256); + var sw = new StringWriter(sb); + using (JsonWriter writer = new JsonTextWriter(sw)) + { + serializer.Serialize(writer, obj); + return sb.ToString(); + } + } + + /// + /// Deserializes the JSON string into an instance of the specified type + /// + /// The type to deserialize into + /// The string containing the JSON + /// The specific settings to use, uses a simple set of default settings if not specified + /// The instance of T being deserialized + /// This will NOT use any global settings to avoid picking up changes that may have been made by other code running in the host (such as user functions) + public static T JsonDeserializeObject(string json, JsonSerializerSettings settings = null) + { + settings = settings ?? _defaultJsonSerializationSettings; + // Following the Newtonsoft implementation in JsonConvert of creating a new JsonSerializer each time. + // https://github.com/JamesNK/Newtonsoft.Json/blob/57025815e564d36821acf778e2c00d02225aab35/Src/Newtonsoft.Json/JsonConvert.cs#L821 + // If performance ends up being an issue could look into creating a single instance of the serializer for each setting. + var serializer = JsonSerializer.Create(settings); + using (JsonReader reader = new JsonTextReader(new StringReader(json))) + { + return serializer.Deserialize(reader); + } + } } \ No newline at end of file diff --git a/test/Integration/test-csx/MultiFunctionTrigger1/function.json b/test/Integration/test-csx/MultiFunctionTrigger1/function.json new file mode 100644 index 000000000..f52bcac4c --- /dev/null +++ b/test/Integration/test-csx/MultiFunctionTrigger1/function.json @@ -0,0 +1,12 @@ +{ + "bindings": [ + { + "name": "changes", + "type": "sqlTrigger", + "direction": "in", + "tableName": "dbo.Products", + "connectionStringSetting": "SqlConnectionString" + } + ], + "disabled": false +} \ No newline at end of file diff --git a/test/Integration/test-csx/MultiFunctionTrigger1/run.csx b/test/Integration/test-csx/MultiFunctionTrigger1/run.csx new file mode 100644 index 000000000..0e843c3ad --- /dev/null +++ b/test/Integration/test-csx/MultiFunctionTrigger1/run.csx @@ -0,0 +1,14 @@ +#load "../Common/Product.csx" +#r "Newtonsoft.Json" +#r "Microsoft.Azure.WebJobs.Extensions.Sql" + +using System.Net; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Primitives; +using Newtonsoft.Json; +using Microsoft.Azure.WebJobs.Extensions.Sql; + +public static void Run(IReadOnlyList> changes, ILogger log) +{ + log.LogInformation("Trigger1 Changes: " + JsonConvert.SerializeObject(changes)); +} \ No newline at end of file diff --git a/test/Integration/test-csx/MultiFunctionTrigger2/function.json b/test/Integration/test-csx/MultiFunctionTrigger2/function.json new file mode 100644 index 000000000..f52bcac4c --- /dev/null +++ b/test/Integration/test-csx/MultiFunctionTrigger2/function.json @@ -0,0 +1,12 @@ +{ + "bindings": [ + { + "name": "changes", + "type": "sqlTrigger", + "direction": "in", + "tableName": "dbo.Products", + "connectionStringSetting": "SqlConnectionString" + } + ], + "disabled": false +} \ No newline at end of file diff --git a/test/Integration/test-csx/MultiFunctionTrigger2/run.csx b/test/Integration/test-csx/MultiFunctionTrigger2/run.csx new file mode 100644 index 000000000..fe3cce42a --- /dev/null +++ b/test/Integration/test-csx/MultiFunctionTrigger2/run.csx @@ -0,0 +1,14 @@ +#load "../Common/Product.csx" +#r "Newtonsoft.Json" +#r "Microsoft.Azure.WebJobs.Extensions.Sql" + +using System.Net; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Primitives; +using Newtonsoft.Json; +using Microsoft.Azure.WebJobs.Extensions.Sql; + +public static void Run(IReadOnlyList> changes, ILogger log) +{ + log.LogInformation("Trigger2 Changes: " + JsonConvert.SerializeObject(changes)); +} \ No newline at end of file diff --git a/test/Integration/test-csx/PrimaryKeyNotPresentTrigger/function.json b/test/Integration/test-csx/PrimaryKeyNotPresentTrigger/function.json new file mode 100644 index 000000000..1e1c80a91 --- /dev/null +++ b/test/Integration/test-csx/PrimaryKeyNotPresentTrigger/function.json @@ -0,0 +1,12 @@ +{ + "bindings": [ + { + "name": "changes", + "type": "sqlTrigger", + "direction": "in", + "tableName": "dbo.ProductsWithoutPrimaryKey", + "connectionStringSetting": "SqlConnectionString" + } + ], + "disabled": false +} \ No newline at end of file diff --git a/test/Integration/test-csx/PrimaryKeyNotPresentTrigger/run.csx b/test/Integration/test-csx/PrimaryKeyNotPresentTrigger/run.csx new file mode 100644 index 000000000..46fb86da7 --- /dev/null +++ b/test/Integration/test-csx/PrimaryKeyNotPresentTrigger/run.csx @@ -0,0 +1,14 @@ +#load "../Common/Product.csx" +#r "Newtonsoft.Json" +#r "Microsoft.Azure.WebJobs.Extensions.Sql" + +using System.Net; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Primitives; +using Newtonsoft.Json; +using Microsoft.Azure.WebJobs.Extensions.Sql; + +public static void Run(IReadOnlyList> changes, ILogger log) +{ + throw new NotImplementedException("Associated test case should fail before the function is invoked."); +} \ No newline at end of file diff --git a/test/Integration/test-csx/ProductsTriggerWithValidation/function.json b/test/Integration/test-csx/ProductsTriggerWithValidation/function.json new file mode 100644 index 000000000..f52bcac4c --- /dev/null +++ b/test/Integration/test-csx/ProductsTriggerWithValidation/function.json @@ -0,0 +1,12 @@ +{ + "bindings": [ + { + "name": "changes", + "type": "sqlTrigger", + "direction": "in", + "tableName": "dbo.Products", + "connectionStringSetting": "SqlConnectionString" + } + ], + "disabled": false +} \ No newline at end of file diff --git a/test/Integration/test-csx/ProductsTriggerWithValidation/run.csx b/test/Integration/test-csx/ProductsTriggerWithValidation/run.csx new file mode 100644 index 000000000..e8007f06c --- /dev/null +++ b/test/Integration/test-csx/ProductsTriggerWithValidation/run.csx @@ -0,0 +1,20 @@ +#load "../Common/Product.csx" +#r "Newtonsoft.Json" +#r "Microsoft.Azure.WebJobs.Extensions.Sql" + +using System.Net; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Primitives; +using Newtonsoft.Json; +using Microsoft.Azure.WebJobs.Extensions.Sql; + +public static void Run(IReadOnlyList> changes, ILogger log) +{ + string expectedMaxBatchSize = Environment.GetEnvironmentVariable("TEST_EXPECTED_MAX_BATCH_SIZE"); + if (!string.IsNullOrEmpty(expectedMaxBatchSize) && int.Parse(expectedMaxBatchSize) != changes.Count) + { + throw new Exception($"Invalid max batch size, got {changes.Count} changes but expected {expectedMaxBatchSize}"); + } + // The output is used to inspect the trigger binding parameter in test methods. + log.LogInformation("SQL Changes: " + Utils.JsonSerializeObject(changes)); +} \ No newline at end of file diff --git a/test/Integration/test-csx/ReservedPrimaryKeyColumnNamesTrigger/function.json b/test/Integration/test-csx/ReservedPrimaryKeyColumnNamesTrigger/function.json new file mode 100644 index 000000000..3660f6a22 --- /dev/null +++ b/test/Integration/test-csx/ReservedPrimaryKeyColumnNamesTrigger/function.json @@ -0,0 +1,12 @@ +{ + "bindings": [ + { + "name": "changes", + "type": "sqlTrigger", + "direction": "in", + "tableName": "dbo.ProductsWithReservedPrimaryKeyColumnNames", + "connectionStringSetting": "SqlConnectionString" + } + ], + "disabled": false +} \ No newline at end of file diff --git a/test/Integration/test-csx/ReservedPrimaryKeyColumnNamesTrigger/run.csx b/test/Integration/test-csx/ReservedPrimaryKeyColumnNamesTrigger/run.csx new file mode 100644 index 000000000..f556e7ca5 --- /dev/null +++ b/test/Integration/test-csx/ReservedPrimaryKeyColumnNamesTrigger/run.csx @@ -0,0 +1,12 @@ +#load "../Common/Product.csx" +#r "Microsoft.Azure.WebJobs.Extensions.Sql" + +using System.Net; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Primitives; +using Microsoft.Azure.WebJobs.Extensions.Sql; + +public static void Run(IReadOnlyList> changes, ILogger log) +{ + throw new NotImplementedException("Associated test case should fail before the function is invoked."); +} \ No newline at end of file diff --git a/test/Integration/test-csx/TableNotPresentTrigger/function.json b/test/Integration/test-csx/TableNotPresentTrigger/function.json new file mode 100644 index 000000000..5dd16ec7e --- /dev/null +++ b/test/Integration/test-csx/TableNotPresentTrigger/function.json @@ -0,0 +1,12 @@ +{ + "bindings": [ + { + "name": "changes", + "type": "sqlTrigger", + "direction": "in", + "tableName": "dbo.TableNotPresent", + "connectionStringSetting": "SqlConnectionString" + } + ], + "disabled": false +} \ No newline at end of file diff --git a/test/Integration/test-csx/TableNotPresentTrigger/run.csx b/test/Integration/test-csx/TableNotPresentTrigger/run.csx new file mode 100644 index 000000000..f556e7ca5 --- /dev/null +++ b/test/Integration/test-csx/TableNotPresentTrigger/run.csx @@ -0,0 +1,12 @@ +#load "../Common/Product.csx" +#r "Microsoft.Azure.WebJobs.Extensions.Sql" + +using System.Net; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Primitives; +using Microsoft.Azure.WebJobs.Extensions.Sql; + +public static void Run(IReadOnlyList> changes, ILogger log) +{ + throw new NotImplementedException("Associated test case should fail before the function is invoked."); +} \ No newline at end of file diff --git a/test/Integration/test-csx/UnsupportedColumnTypesTrigger/function.json b/test/Integration/test-csx/UnsupportedColumnTypesTrigger/function.json new file mode 100644 index 000000000..705397ccf --- /dev/null +++ b/test/Integration/test-csx/UnsupportedColumnTypesTrigger/function.json @@ -0,0 +1,12 @@ +{ + "bindings": [ + { + "name": "changes", + "type": "sqlTrigger", + "direction": "in", + "tableName": "dbo.ProductsWithUnsupportedColumnTypes", + "connectionStringSetting": "SqlConnectionString" + } + ], + "disabled": false +} \ No newline at end of file diff --git a/test/Integration/test-csx/UnsupportedColumnTypesTrigger/run.csx b/test/Integration/test-csx/UnsupportedColumnTypesTrigger/run.csx new file mode 100644 index 000000000..f556e7ca5 --- /dev/null +++ b/test/Integration/test-csx/UnsupportedColumnTypesTrigger/run.csx @@ -0,0 +1,12 @@ +#load "../Common/Product.csx" +#r "Microsoft.Azure.WebJobs.Extensions.Sql" + +using System.Net; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Primitives; +using Microsoft.Azure.WebJobs.Extensions.Sql; + +public static void Run(IReadOnlyList> changes, ILogger log) +{ + throw new NotImplementedException("Associated test case should fail before the function is invoked."); +} \ No newline at end of file From 9c8ab5f4e88ce2e70670d9f949a0a346e0e50728 Mon Sep 17 00:00:00 2001 From: Maddy Koripalli Date: Fri, 14 Apr 2023 11:33:54 -0700 Subject: [PATCH 2/7] enable csx tests --- .../SqlTriggerBindingIntegrationTests.cs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/test/Integration/SqlTriggerBindingIntegrationTests.cs b/test/Integration/SqlTriggerBindingIntegrationTests.cs index 431af210f..d8bf7f628 100644 --- a/test/Integration/SqlTriggerBindingIntegrationTests.cs +++ b/test/Integration/SqlTriggerBindingIntegrationTests.cs @@ -31,7 +31,6 @@ public SqlTriggerBindingIntegrationTests(ITestOutputHelper output = null) : base /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.CSharpscript)] public async Task SingleOperationTriggerTest(SupportedLanguages lang) { this.SetChangeTrackingForTable("Products"); @@ -80,7 +79,6 @@ await this.WaitForProductChanges( /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.CSharpscript)] public async Task BatchSizeOverrideTriggerTest(SupportedLanguages lang) { // Use enough items to require 4 batches to be processed but then @@ -124,7 +122,6 @@ await this.WaitForProductChanges( /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.CSharpscript)] public async Task MaxBatchSizeOverrideTriggerTest(SupportedLanguages lang) { // Use enough items to require 4 batches to be processed but then @@ -168,7 +165,6 @@ await this.WaitForProductChanges( /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.CSharpscript)] public async Task PollingIntervalOverrideTriggerTest(SupportedLanguages lang) { const int firstId = 1; @@ -211,7 +207,6 @@ await this.WaitForProductChanges( /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.CSharpscript)] public async Task MultiOperationTriggerTest(SupportedLanguages lang) { int firstId = 1; @@ -293,7 +288,6 @@ await this.WaitForProductChanges( /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.CSharpscript)] public async Task MultiFunctionTriggerTest(SupportedLanguages lang) { const string Trigger1Changes = "Trigger1 Changes: "; @@ -420,7 +414,6 @@ public async Task MultiFunctionTriggerTest(SupportedLanguages lang) /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.CSharpscript)] public async Task MultiHostTriggerTest(SupportedLanguages lang) { this.SetChangeTrackingForTable("Products"); @@ -472,7 +465,6 @@ await this.WaitForProductChanges( /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.CSharpscript)] public void TableNotPresentTriggerTest(SupportedLanguages lang) { this.StartFunctionHostAndWaitForError( @@ -487,7 +479,6 @@ public void TableNotPresentTriggerTest(SupportedLanguages lang) /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.CSharpscript)] public void PrimaryKeyNotCreatedTriggerTest(SupportedLanguages lang) { this.StartFunctionHostAndWaitForError( @@ -503,7 +494,6 @@ public void PrimaryKeyNotCreatedTriggerTest(SupportedLanguages lang) /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.CSharpscript)] public void ReservedPrimaryKeyColumnNamesTriggerTest(SupportedLanguages lang) { this.StartFunctionHostAndWaitForError( @@ -519,7 +509,6 @@ public void ReservedPrimaryKeyColumnNamesTriggerTest(SupportedLanguages lang) /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.CSharpscript)] public void UnsupportedColumnTypesTriggerTest(SupportedLanguages lang) { this.StartFunctionHostAndWaitForError( @@ -535,7 +524,6 @@ public void UnsupportedColumnTypesTriggerTest(SupportedLanguages lang) /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.CSharpscript)] public void ChangeTrackingNotEnabledTriggerTest(SupportedLanguages lang) { this.StartFunctionHostAndWaitForError( @@ -572,7 +560,6 @@ public async void GetMetricsTest() /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.CSharpscript)] public void UnsupportedDatabaseThrows(SupportedLanguages lang) { // Change database compat level to unsupported version From ce46d2738583512840fb04272553f0ace474775e Mon Sep 17 00:00:00 2001 From: Maddy Koripalli Date: Fri, 14 Apr 2023 13:12:37 -0700 Subject: [PATCH 3/7] add copy trigger sample --- test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj b/test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj index 5c8d1d3fb..013b3eb83 100644 --- a/test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj +++ b/test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj @@ -69,6 +69,7 @@ <_CSharpScriptCopyItems Include="..\samples\samples-csharpscript\InputBindingSamples\**\*.*" /> <_CSharpScriptCopyItems Include="..\samples\samples-csharpscript\OutputBindingSamples\**\*.*" /> + <_CSharpScriptCopyItems Include="..\samples\samples-csharpscript\TriggerBindingSamples\**\*.*" /> <_CSharpScriptCopyItems Include="Integration\test-csx\**\*.*" /> From 5b806b711becaa663236bf20bfbedb3dc305980d Mon Sep 17 00:00:00 2001 From: Maddy Koripalli Date: Mon, 17 Apr 2023 10:57:58 -0700 Subject: [PATCH 4/7] use utils.josnserialize --- test/Integration/test-csx/MultiFunctionTrigger1/run.csx | 2 +- test/Integration/test-csx/MultiFunctionTrigger2/run.csx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Integration/test-csx/MultiFunctionTrigger1/run.csx b/test/Integration/test-csx/MultiFunctionTrigger1/run.csx index 0e843c3ad..315ba190c 100644 --- a/test/Integration/test-csx/MultiFunctionTrigger1/run.csx +++ b/test/Integration/test-csx/MultiFunctionTrigger1/run.csx @@ -10,5 +10,5 @@ using Microsoft.Azure.WebJobs.Extensions.Sql; public static void Run(IReadOnlyList> changes, ILogger log) { - log.LogInformation("Trigger1 Changes: " + JsonConvert.SerializeObject(changes)); + log.LogInformation("Trigger1 Changes: " + Utils.JsonSerializeObject(changes)); } \ No newline at end of file diff --git a/test/Integration/test-csx/MultiFunctionTrigger2/run.csx b/test/Integration/test-csx/MultiFunctionTrigger2/run.csx index fe3cce42a..df8a347ce 100644 --- a/test/Integration/test-csx/MultiFunctionTrigger2/run.csx +++ b/test/Integration/test-csx/MultiFunctionTrigger2/run.csx @@ -10,5 +10,5 @@ using Microsoft.Azure.WebJobs.Extensions.Sql; public static void Run(IReadOnlyList> changes, ILogger log) { - log.LogInformation("Trigger2 Changes: " + JsonConvert.SerializeObject(changes)); + log.LogInformation("Trigger2 Changes: " + Utils.JsonSerializeObject(changes)); } \ No newline at end of file From ae312e53dff0e062a0104b3f3b58a550792c03f5 Mon Sep 17 00:00:00 2001 From: Maddy Koripalli Date: Mon, 17 Apr 2023 11:52:13 -0700 Subject: [PATCH 5/7] separate utils file --- test/Integration/test-csx/Common/Product.csx | 68 ----------------- test/Integration/test-csx/Common/utils.csx | 75 +++++++++++++++++++ .../test-csx/MultiFunctionTrigger1/run.csx | 1 + .../test-csx/MultiFunctionTrigger2/run.csx | 1 + .../ProductsTriggerWithValidation/run.csx | 1 + 5 files changed, 78 insertions(+), 68 deletions(-) create mode 100644 test/Integration/test-csx/Common/utils.csx diff --git a/test/Integration/test-csx/Common/Product.csx b/test/Integration/test-csx/Common/Product.csx index bbc9247b3..b6676788b 100644 --- a/test/Integration/test-csx/Common/Product.csx +++ b/test/Integration/test-csx/Common/Product.csx @@ -1,16 +1,10 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -#r "Newtonsoft.Json" - using System; using System.Linq; using System.IO; using System.Text; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; public class Product { @@ -242,66 +236,4 @@ public class ProductUtilities } return products; } -} - -public static class Utils -{ - /// - /// Default JSON serializer settings to use - /// - private static readonly JsonSerializerSettings _defaultJsonSerializationSettings; - - static Utils() - { - _defaultJsonSerializationSettings = new JsonSerializerSettings - { - ContractResolver = new DefaultContractResolver() - }; - } - - /// - /// Serializes the specified object into a JSON string. - /// - /// The object to serialize - /// The specific settings to use, uses a simple set of default settings if not specified - /// The serialized JSON string - /// This will NOT use any global settings to avoid picking up changes that may have been made by other code running in the host (such as user functions) - public static string JsonSerializeObject(object obj, JsonSerializerSettings settings = null) - { - settings = settings ?? _defaultJsonSerializationSettings; - // Following the Newtonsoft implementation in JsonConvert of creating a new JsonSerializer each time. - // https://github.com/JamesNK/Newtonsoft.Json/blob/57025815e564d36821acf778e2c00d02225aab35/Src/Newtonsoft.Json/JsonConvert.cs#L612 - // If performance ends up being an issue could look into creating a single instance of the serializer for each setting. - var serializer = JsonSerializer.Create(settings); - // 256 is value used by Newtonsoft by default - helps avoid having to expand it too many times for larger strings - // https://github.com/JamesNK/Newtonsoft.Json/blob/57025815e564d36821acf778e2c00d02225aab35/Src/Newtonsoft.Json/JsonConvert.cs#L659 - var sb = new StringBuilder(256); - var sw = new StringWriter(sb); - using (JsonWriter writer = new JsonTextWriter(sw)) - { - serializer.Serialize(writer, obj); - return sb.ToString(); - } - } - - /// - /// Deserializes the JSON string into an instance of the specified type - /// - /// The type to deserialize into - /// The string containing the JSON - /// The specific settings to use, uses a simple set of default settings if not specified - /// The instance of T being deserialized - /// This will NOT use any global settings to avoid picking up changes that may have been made by other code running in the host (such as user functions) - public static T JsonDeserializeObject(string json, JsonSerializerSettings settings = null) - { - settings = settings ?? _defaultJsonSerializationSettings; - // Following the Newtonsoft implementation in JsonConvert of creating a new JsonSerializer each time. - // https://github.com/JamesNK/Newtonsoft.Json/blob/57025815e564d36821acf778e2c00d02225aab35/Src/Newtonsoft.Json/JsonConvert.cs#L821 - // If performance ends up being an issue could look into creating a single instance of the serializer for each setting. - var serializer = JsonSerializer.Create(settings); - using (JsonReader reader = new JsonTextReader(new StringReader(json))) - { - return serializer.Deserialize(reader); - } - } } \ No newline at end of file diff --git a/test/Integration/test-csx/Common/utils.csx b/test/Integration/test-csx/Common/utils.csx new file mode 100644 index 000000000..426bacf2b --- /dev/null +++ b/test/Integration/test-csx/Common/utils.csx @@ -0,0 +1,75 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +#r "Newtonsoft.Json" + +using System; +using System.Linq; +using System.IO; +using System.Text; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +public static class Utils +{ + /// + /// Default JSON serializer settings to use + /// + private static readonly JsonSerializerSettings _defaultJsonSerializationSettings; + + static Utils() + { + _defaultJsonSerializationSettings = new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver() + }; + } + + /// + /// Serializes the specified object into a JSON string. + /// + /// The object to serialize + /// The specific settings to use, uses a simple set of default settings if not specified + /// The serialized JSON string + /// This will NOT use any global settings to avoid picking up changes that may have been made by other code running in the host (such as user functions) + public static string JsonSerializeObject(object obj, JsonSerializerSettings settings = null) + { + settings = settings ?? _defaultJsonSerializationSettings; + // Following the Newtonsoft implementation in JsonConvert of creating a new JsonSerializer each time. + // https://github.com/JamesNK/Newtonsoft.Json/blob/57025815e564d36821acf778e2c00d02225aab35/Src/Newtonsoft.Json/JsonConvert.cs#L612 + // If performance ends up being an issue could look into creating a single instance of the serializer for each setting. + var serializer = JsonSerializer.Create(settings); + // 256 is value used by Newtonsoft by default - helps avoid having to expand it too many times for larger strings + // https://github.com/JamesNK/Newtonsoft.Json/blob/57025815e564d36821acf778e2c00d02225aab35/Src/Newtonsoft.Json/JsonConvert.cs#L659 + var sb = new StringBuilder(256); + var sw = new StringWriter(sb); + using (JsonWriter writer = new JsonTextWriter(sw)) + { + serializer.Serialize(writer, obj); + return sb.ToString(); + } + } + + /// + /// Deserializes the JSON string into an instance of the specified type + /// + /// The type to deserialize into + /// The string containing the JSON + /// The specific settings to use, uses a simple set of default settings if not specified + /// The instance of T being deserialized + /// This will NOT use any global settings to avoid picking up changes that may have been made by other code running in the host (such as user functions) + public static T JsonDeserializeObject(string json, JsonSerializerSettings settings = null) + { + settings = settings ?? _defaultJsonSerializationSettings; + // Following the Newtonsoft implementation in JsonConvert of creating a new JsonSerializer each time. + // https://github.com/JamesNK/Newtonsoft.Json/blob/57025815e564d36821acf778e2c00d02225aab35/Src/Newtonsoft.Json/JsonConvert.cs#L821 + // If performance ends up being an issue could look into creating a single instance of the serializer for each setting. + var serializer = JsonSerializer.Create(settings); + using (JsonReader reader = new JsonTextReader(new StringReader(json))) + { + return serializer.Deserialize(reader); + } + } +} \ No newline at end of file diff --git a/test/Integration/test-csx/MultiFunctionTrigger1/run.csx b/test/Integration/test-csx/MultiFunctionTrigger1/run.csx index 315ba190c..097a5b215 100644 --- a/test/Integration/test-csx/MultiFunctionTrigger1/run.csx +++ b/test/Integration/test-csx/MultiFunctionTrigger1/run.csx @@ -1,4 +1,5 @@ #load "../Common/Product.csx" +#load "../Common/utils.csx" #r "Newtonsoft.Json" #r "Microsoft.Azure.WebJobs.Extensions.Sql" diff --git a/test/Integration/test-csx/MultiFunctionTrigger2/run.csx b/test/Integration/test-csx/MultiFunctionTrigger2/run.csx index df8a347ce..841553697 100644 --- a/test/Integration/test-csx/MultiFunctionTrigger2/run.csx +++ b/test/Integration/test-csx/MultiFunctionTrigger2/run.csx @@ -1,4 +1,5 @@ #load "../Common/Product.csx" +#load "../Common/utils.csx" #r "Newtonsoft.Json" #r "Microsoft.Azure.WebJobs.Extensions.Sql" diff --git a/test/Integration/test-csx/ProductsTriggerWithValidation/run.csx b/test/Integration/test-csx/ProductsTriggerWithValidation/run.csx index e8007f06c..a39f18771 100644 --- a/test/Integration/test-csx/ProductsTriggerWithValidation/run.csx +++ b/test/Integration/test-csx/ProductsTriggerWithValidation/run.csx @@ -1,4 +1,5 @@ #load "../Common/Product.csx" +#load "../Common/utils.csx" #r "Newtonsoft.Json" #r "Microsoft.Azure.WebJobs.Extensions.Sql" From 2f509ea3e78279005663081f1955dd441d9c3151 Mon Sep 17 00:00:00 2001 From: Maddy Koripalli Date: Mon, 17 Apr 2023 13:56:59 -0700 Subject: [PATCH 6/7] reuse utils from sql extension --- test/Integration/test-csx/Common/Product.csx | 6 -- test/Integration/test-csx/Common/utils.csx | 75 ------------------- .../test-csx/MultiFunctionTrigger1/run.csx | 3 +- .../test-csx/MultiFunctionTrigger2/run.csx | 2 +- .../ProductsTriggerWithValidation/run.csx | 3 +- 5 files changed, 3 insertions(+), 86 deletions(-) delete mode 100644 test/Integration/test-csx/Common/utils.csx diff --git a/test/Integration/test-csx/Common/Product.csx b/test/Integration/test-csx/Common/Product.csx index b6676788b..c84985b96 100644 --- a/test/Integration/test-csx/Common/Product.csx +++ b/test/Integration/test-csx/Common/Product.csx @@ -1,11 +1,5 @@ // 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.Linq; -using System.IO; -using System.Text; - public class Product { public int ProductId { get; set; } diff --git a/test/Integration/test-csx/Common/utils.csx b/test/Integration/test-csx/Common/utils.csx deleted file mode 100644 index 426bacf2b..000000000 --- a/test/Integration/test-csx/Common/utils.csx +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. - -#r "Newtonsoft.Json" - -using System; -using System.Linq; -using System.IO; -using System.Text; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - -public static class Utils -{ - /// - /// Default JSON serializer settings to use - /// - private static readonly JsonSerializerSettings _defaultJsonSerializationSettings; - - static Utils() - { - _defaultJsonSerializationSettings = new JsonSerializerSettings - { - ContractResolver = new DefaultContractResolver() - }; - } - - /// - /// Serializes the specified object into a JSON string. - /// - /// The object to serialize - /// The specific settings to use, uses a simple set of default settings if not specified - /// The serialized JSON string - /// This will NOT use any global settings to avoid picking up changes that may have been made by other code running in the host (such as user functions) - public static string JsonSerializeObject(object obj, JsonSerializerSettings settings = null) - { - settings = settings ?? _defaultJsonSerializationSettings; - // Following the Newtonsoft implementation in JsonConvert of creating a new JsonSerializer each time. - // https://github.com/JamesNK/Newtonsoft.Json/blob/57025815e564d36821acf778e2c00d02225aab35/Src/Newtonsoft.Json/JsonConvert.cs#L612 - // If performance ends up being an issue could look into creating a single instance of the serializer for each setting. - var serializer = JsonSerializer.Create(settings); - // 256 is value used by Newtonsoft by default - helps avoid having to expand it too many times for larger strings - // https://github.com/JamesNK/Newtonsoft.Json/blob/57025815e564d36821acf778e2c00d02225aab35/Src/Newtonsoft.Json/JsonConvert.cs#L659 - var sb = new StringBuilder(256); - var sw = new StringWriter(sb); - using (JsonWriter writer = new JsonTextWriter(sw)) - { - serializer.Serialize(writer, obj); - return sb.ToString(); - } - } - - /// - /// Deserializes the JSON string into an instance of the specified type - /// - /// The type to deserialize into - /// The string containing the JSON - /// The specific settings to use, uses a simple set of default settings if not specified - /// The instance of T being deserialized - /// This will NOT use any global settings to avoid picking up changes that may have been made by other code running in the host (such as user functions) - public static T JsonDeserializeObject(string json, JsonSerializerSettings settings = null) - { - settings = settings ?? _defaultJsonSerializationSettings; - // Following the Newtonsoft implementation in JsonConvert of creating a new JsonSerializer each time. - // https://github.com/JamesNK/Newtonsoft.Json/blob/57025815e564d36821acf778e2c00d02225aab35/Src/Newtonsoft.Json/JsonConvert.cs#L821 - // If performance ends up being an issue could look into creating a single instance of the serializer for each setting. - var serializer = JsonSerializer.Create(settings); - using (JsonReader reader = new JsonTextReader(new StringReader(json))) - { - return serializer.Deserialize(reader); - } - } -} \ No newline at end of file diff --git a/test/Integration/test-csx/MultiFunctionTrigger1/run.csx b/test/Integration/test-csx/MultiFunctionTrigger1/run.csx index 097a5b215..ae6961722 100644 --- a/test/Integration/test-csx/MultiFunctionTrigger1/run.csx +++ b/test/Integration/test-csx/MultiFunctionTrigger1/run.csx @@ -1,5 +1,4 @@ #load "../Common/Product.csx" -#load "../Common/utils.csx" #r "Newtonsoft.Json" #r "Microsoft.Azure.WebJobs.Extensions.Sql" @@ -11,5 +10,5 @@ using Microsoft.Azure.WebJobs.Extensions.Sql; public static void Run(IReadOnlyList> changes, ILogger log) { - log.LogInformation("Trigger1 Changes: " + Utils.JsonSerializeObject(changes)); + log.LogInformation("Trigger1 Changes: " + Microsoft.Azure.WebJobs.Extensions.Sql.Utils.JsonSerializeObject(changes)); } \ No newline at end of file diff --git a/test/Integration/test-csx/MultiFunctionTrigger2/run.csx b/test/Integration/test-csx/MultiFunctionTrigger2/run.csx index 841553697..609feef69 100644 --- a/test/Integration/test-csx/MultiFunctionTrigger2/run.csx +++ b/test/Integration/test-csx/MultiFunctionTrigger2/run.csx @@ -11,5 +11,5 @@ using Microsoft.Azure.WebJobs.Extensions.Sql; public static void Run(IReadOnlyList> changes, ILogger log) { - log.LogInformation("Trigger2 Changes: " + Utils.JsonSerializeObject(changes)); + log.LogInformation("Trigger2 Changes: " + Microsoft.Azure.WebJobs.Extensions.Sql.Utils.JsonSerializeObject(changes)); } \ No newline at end of file diff --git a/test/Integration/test-csx/ProductsTriggerWithValidation/run.csx b/test/Integration/test-csx/ProductsTriggerWithValidation/run.csx index a39f18771..a1320ae5f 100644 --- a/test/Integration/test-csx/ProductsTriggerWithValidation/run.csx +++ b/test/Integration/test-csx/ProductsTriggerWithValidation/run.csx @@ -1,5 +1,4 @@ #load "../Common/Product.csx" -#load "../Common/utils.csx" #r "Newtonsoft.Json" #r "Microsoft.Azure.WebJobs.Extensions.Sql" @@ -17,5 +16,5 @@ public static void Run(IReadOnlyList> changes, ILogger log) throw new Exception($"Invalid max batch size, got {changes.Count} changes but expected {expectedMaxBatchSize}"); } // The output is used to inspect the trigger binding parameter in test methods. - log.LogInformation("SQL Changes: " + Utils.JsonSerializeObject(changes)); + log.LogInformation("SQL Changes: " + Microsoft.Azure.WebJobs.Extensions.Sql.Utils.JsonSerializeObject(changes)); } \ No newline at end of file From c752af40c190a94f1a287d2b19082d8c8ae017db Mon Sep 17 00:00:00 2001 From: Maddy Koripalli Date: Mon, 17 Apr 2023 16:05:11 -0700 Subject: [PATCH 7/7] remove deleted references --- test/Integration/test-csx/MultiFunctionTrigger2/run.csx | 1 - 1 file changed, 1 deletion(-) diff --git a/test/Integration/test-csx/MultiFunctionTrigger2/run.csx b/test/Integration/test-csx/MultiFunctionTrigger2/run.csx index 609feef69..570b7cb66 100644 --- a/test/Integration/test-csx/MultiFunctionTrigger2/run.csx +++ b/test/Integration/test-csx/MultiFunctionTrigger2/run.csx @@ -1,5 +1,4 @@ #load "../Common/Product.csx" -#load "../Common/utils.csx" #r "Newtonsoft.Json" #r "Microsoft.Azure.WebJobs.Extensions.Sql"