diff --git a/samples/samples-js/ProductsTrigger/function.json b/samples/samples-js/ProductsTrigger/function.json
index 3bc5a8141..e277c5e39 100644
--- a/samples/samples-js/ProductsTrigger/function.json
+++ b/samples/samples-js/ProductsTrigger/function.json
@@ -4,7 +4,7 @@
"name": "changes",
"type": "sqlTrigger",
"direction": "in",
- "tableName": "Products",
+ "tableName": "dbo.Products",
"connectionStringSetting": "SqlConnectionString"
}
],
diff --git a/samples/samples-powershell/ProductsTrigger/function.json b/samples/samples-powershell/ProductsTrigger/function.json
index 3bc5a8141..e277c5e39 100644
--- a/samples/samples-powershell/ProductsTrigger/function.json
+++ b/samples/samples-powershell/ProductsTrigger/function.json
@@ -4,7 +4,7 @@
"name": "changes",
"type": "sqlTrigger",
"direction": "in",
- "tableName": "Products",
+ "tableName": "dbo.Products",
"connectionStringSetting": "SqlConnectionString"
}
],
diff --git a/samples/samples-python/ProductsTrigger/function.json b/samples/samples-python/ProductsTrigger/function.json
index 3bc5a8141..e277c5e39 100644
--- a/samples/samples-python/ProductsTrigger/function.json
+++ b/samples/samples-python/ProductsTrigger/function.json
@@ -4,7 +4,7 @@
"name": "changes",
"type": "sqlTrigger",
"direction": "in",
- "tableName": "Products",
+ "tableName": "dbo.Products",
"connectionStringSetting": "SqlConnectionString"
}
],
diff --git a/test/Integration/SqlTriggerBindingIntegrationTestBase.cs b/test/Integration/SqlTriggerBindingIntegrationTestBase.cs
index 20976db9b..f1db431f2 100644
--- a/test/Integration/SqlTriggerBindingIntegrationTestBase.cs
+++ b/test/Integration/SqlTriggerBindingIntegrationTestBase.cs
@@ -145,7 +145,7 @@ void MonitorOutputData(object sender, DataReceivedEventArgs e)
/// Name of the user function that should cause error in trigger listener
/// Whether the functions host should be launched from test folder
/// Expected error message string
- protected void StartFunctionHostAndWaitForError(string functionName, bool useTestFolder, string expectedErrorMessage)
+ protected void StartFunctionHostAndWaitForError(string functionName, SupportedLanguages lang, bool useTestFolder, string expectedErrorMessage)
{
string errorMessage = null;
var tcs = new TaskCompletionSource();
@@ -165,7 +165,7 @@ void OutputHandler(object sender, DataReceivedEventArgs e)
};
// All trigger integration tests are only using C# functions for testing at the moment.
- this.StartFunctionHost(functionName, SupportedLanguages.CSharp, useTestFolder, OutputHandler);
+ this.StartFunctionHost(functionName, lang, useTestFolder, OutputHandler);
// The functions host generally logs the error message within a second after starting up.
const int BufferTimeForErrorInSeconds = 15;
diff --git a/test/Integration/SqlTriggerBindingIntegrationTests.cs b/test/Integration/SqlTriggerBindingIntegrationTests.cs
index e13f24227..0e6984ebe 100644
--- a/test/Integration/SqlTriggerBindingIntegrationTests.cs
+++ b/test/Integration/SqlTriggerBindingIntegrationTests.cs
@@ -78,8 +78,10 @@ await this.WaitForProductChanges(
/// Verifies that manually setting the batch size using the original config var correctly changes the
/// number of changes processed at once.
///
- [Fact]
- public async Task BatchSizeOverrideTriggerTest()
+ [Theory]
+ [SqlInlineData()]
+ [UnsupportedLanguages(SupportedLanguages.Java, SupportedLanguages.OutOfProc)]
+ public async Task BatchSizeOverrideTriggerTest(SupportedLanguages lang)
{
// Use enough items to require 4 batches to be processed but then
// set the max batch size to the same value so they can all be processed in one
@@ -97,7 +99,7 @@ public async Task BatchSizeOverrideTriggerTest()
maxBatchSize.ToString());
this.StartFunctionHost(
nameof(ProductsTriggerWithValidation),
- SupportedLanguages.CSharp,
+ lang,
useTestFolder: true,
customOutputHandler: handler,
environmentVariables: new Dictionary() {
@@ -120,8 +122,10 @@ await this.WaitForProductChanges(
///
/// Verifies that manually setting the max batch size correctly changes the number of changes processed at once
///
- [Fact]
- public async Task MaxBatchSizeOverrideTriggerTest()
+ [Theory]
+ [SqlInlineData()]
+ [UnsupportedLanguages(SupportedLanguages.Java, SupportedLanguages.OutOfProc)]
+ public async Task MaxBatchSizeOverrideTriggerTest(SupportedLanguages lang)
{
// Use enough items to require 4 batches to be processed but then
// set the max batch size to the same value so they can all be processed in one
@@ -139,7 +143,7 @@ public async Task MaxBatchSizeOverrideTriggerTest()
maxBatchSize.ToString());
this.StartFunctionHost(
nameof(ProductsTriggerWithValidation),
- SupportedLanguages.CSharp,
+ lang,
useTestFolder: true,
customOutputHandler: handler,
environmentVariables: new Dictionary() {
@@ -203,13 +207,15 @@ 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.
///
- [Fact]
- public async Task MultiOperationTriggerTest()
+ [Theory]
+ [SqlInlineData()]
+ [UnsupportedLanguages(SupportedLanguages.Java)]
+ public async Task MultiOperationTriggerTest(SupportedLanguages lang)
{
int firstId = 1;
int lastId = 5;
this.SetChangeTrackingForTable("Products");
- this.StartFunctionHost(nameof(ProductsTrigger), SupportedLanguages.CSharp);
+ this.StartFunctionHost(nameof(ProductsTrigger), lang);
// 1. Insert + multiple updates to a row are treated as single insert with latest row values.
await this.WaitForProductChanges(
@@ -408,15 +414,17 @@ public async Task MultiFunctionTriggerTest()
///
/// Ensures correct functionality with user functions running across multiple functions host processes.
///
- [Fact]
- public async Task MultiHostTriggerTest()
+ [Theory]
+ [SqlInlineData()]
+ [UnsupportedLanguages(SupportedLanguages.Java)]
+ public async Task MultiHostTriggerTest(SupportedLanguages lang)
{
this.SetChangeTrackingForTable("Products");
// Prepare three function host processes.
- this.StartFunctionHost(nameof(ProductsTrigger), SupportedLanguages.CSharp);
- this.StartFunctionHost(nameof(ProductsTrigger), SupportedLanguages.CSharp);
- this.StartFunctionHost(nameof(ProductsTrigger), SupportedLanguages.CSharp);
+ this.StartFunctionHost(nameof(ProductsTrigger), lang);
+ this.StartFunctionHost(nameof(ProductsTrigger), lang);
+ this.StartFunctionHost(nameof(ProductsTrigger), lang);
int firstId = 1;
int lastId = 90;
@@ -463,6 +471,7 @@ public void TableNotPresentTriggerTest()
{
this.StartFunctionHostAndWaitForError(
nameof(TableNotPresentTrigger),
+ SupportedLanguages.CSharp,
true,
"Could not find table: 'dbo.TableNotPresent'.");
}
@@ -475,6 +484,7 @@ public void PrimaryKeyNotCreatedTriggerTest()
{
this.StartFunctionHostAndWaitForError(
nameof(PrimaryKeyNotPresentTrigger),
+ SupportedLanguages.CSharp,
true,
"Could not find primary key created in table: 'dbo.ProductsWithoutPrimaryKey'.");
}
@@ -488,6 +498,7 @@ public void ReservedPrimaryKeyColumnNamesTriggerTest()
{
this.StartFunctionHostAndWaitForError(
nameof(ReservedPrimaryKeyColumnNamesTrigger),
+ SupportedLanguages.CSharp,
true,
"Found reserved column name(s): '_az_func_ChangeVersion', '_az_func_AttemptCount', '_az_func_LeaseExpirationTime' in table: 'dbo.ProductsWithReservedPrimaryKeyColumnNames'." +
" Please rename them to be able to use trigger binding.");
@@ -501,6 +512,7 @@ public void UnsupportedColumnTypesTriggerTest()
{
this.StartFunctionHostAndWaitForError(
nameof(UnsupportedColumnTypesTrigger),
+ SupportedLanguages.CSharp,
true,
"Found column(s) with unsupported type(s): 'Location' (type: geography), 'Geometry' (type: geometry), 'Organization' (type: hierarchyid)" +
" in table: 'dbo.ProductsWithUnsupportedColumnTypes'.");
@@ -509,11 +521,14 @@ public void UnsupportedColumnTypesTriggerTest()
///
/// Tests the error message when change tracking is not enabled on the user table.
///
- [Fact]
- public void ChangeTrackingNotEnabledTriggerTest()
+ [Theory]
+ [SqlInlineData()]
+ [UnsupportedLanguages(SupportedLanguages.Java)]
+ public void ChangeTrackingNotEnabledTriggerTest(SupportedLanguages lang)
{
this.StartFunctionHostAndWaitForError(
nameof(ProductsTrigger),
+ lang,
false,
"Could not find change tracking enabled for table: 'dbo.Products'.");
}
@@ -541,14 +556,17 @@ public async void GetMetricsTest()
///
/// Tests that when using an unsupported database the expected error is thrown
///
- [Fact]
- public void UnsupportedDatabaseThrows()
+ [Theory]
+ [SqlInlineData()]
+ [UnsupportedLanguages(SupportedLanguages.Java)]
+ public void UnsupportedDatabaseThrows(SupportedLanguages lang)
{
// Change database compat level to unsupported version
this.ExecuteNonQuery($"ALTER DATABASE {this.DatabaseName} SET COMPATIBILITY_LEVEL = 120");
this.StartFunctionHostAndWaitForError(
nameof(ProductsTrigger),
+ lang,
false,
"SQL bindings require a database compatibility level of 130 or higher to function. Current compatibility level = 120");
}
diff --git a/test/Integration/test-js/ProductsTriggerWithValidation/function.json b/test/Integration/test-js/ProductsTriggerWithValidation/function.json
new file mode 100644
index 000000000..e277c5e39
--- /dev/null
+++ b/test/Integration/test-js/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-js/ProductsTriggerWithValidation/index.js b/test/Integration/test-js/ProductsTriggerWithValidation/index.js
new file mode 100644
index 000000000..4ed3d4fc9
--- /dev/null
+++ b/test/Integration/test-js/ProductsTriggerWithValidation/index.js
@@ -0,0 +1,10 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+module.exports = async function (context, changes) {
+ const expectedMaxBatchSize = process.env["TEST_EXPECTED_MAX_BATCH_SIZE"]
+ if (expectedMaxBatchSize && expectedMaxBatchSize != changes.length) {
+ throw new Error(`Invalid max batch size, got ${changes.length} changes but expected ${expectedMaxBatchSize}`)
+ }
+ context.log(`SQL Changes: ${JSON.stringify(changes)}`)
+}
\ No newline at end of file
diff --git a/test/Integration/test-powershell/ProductsTriggerWithValidation/function.json b/test/Integration/test-powershell/ProductsTriggerWithValidation/function.json
new file mode 100644
index 000000000..e277c5e39
--- /dev/null
+++ b/test/Integration/test-powershell/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-powershell/ProductsTriggerWithValidation/run.ps1 b/test/Integration/test-powershell/ProductsTriggerWithValidation/run.ps1
new file mode 100644
index 000000000..8ce36e8da
--- /dev/null
+++ b/test/Integration/test-powershell/ProductsTriggerWithValidation/run.ps1
@@ -0,0 +1,15 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+
+using namespace System.Net
+
+param($changes)
+
+$expectedMaxBatchSize = $env:TEST_EXPECTED_MAX_BATCH_SIZE
+if ($expectedMaxBatchSize -and $expectedMaxBatchSize -ne $changes.Count) {
+ throw "Invalid max batch size, got $($changes.Count) changes but expected $expectedMaxBatchSize"
+}
+
+$changesJson = $changes | ConvertTo-Json
+$changesJson = $changesJson -replace [Environment]::NewLine,"";
+Write-Host "SQL Changes: $changesJson"
\ No newline at end of file
diff --git a/test/Integration/test-python/ProductsTriggerWithValidation/__init__.py b/test/Integration/test-python/ProductsTriggerWithValidation/__init__.py
new file mode 100644
index 000000000..fbfffcf2d
--- /dev/null
+++ b/test/Integration/test-python/ProductsTriggerWithValidation/__init__.py
@@ -0,0 +1,13 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import json
+import logging
+import os
+
+def main(changes):
+ expectedMaxBatchSize = os.environ.get("TEST_EXPECTED_MAX_BATCH_SIZE")
+ length = len(json.loads(changes))
+ if expectedMaxBatchSize and int(expectedMaxBatchSize) != length:
+ raise Exception("Invalid max batch size, got %d changes but expected %s" % (length, expectedMaxBatchSize))
+ logging.info("SQL Changes: %s", changes)
diff --git a/test/Integration/test-python/ProductsTriggerWithValidation/function.json b/test/Integration/test-python/ProductsTriggerWithValidation/function.json
new file mode 100644
index 000000000..e277c5e39
--- /dev/null
+++ b/test/Integration/test-python/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