diff --git a/tests/endtoend/sql_functions/sql_input/function.json b/tests/endtoend/sql_functions/sql_input/function.json index 87b67886e..38ec00f6f 100644 --- a/tests/endtoend/sql_functions/sql_input/function.json +++ b/tests/endtoend/sql_functions/sql_input/function.json @@ -8,7 +8,8 @@ "direction": "in", "methods": [ "get" - ] + ], + "route": "sql_input/{productid}" }, { "name": "$return", @@ -19,8 +20,9 @@ "name": "products", "type": "sql", "direction": "in", - "commandText": "SELECT * FROM Products", + "commandText": "SELECT * FROM Products WHERE ProductId = @ProductId", "commandType": "Text", + "parameters": "@ProductId={productid}", "connectionStringSetting": "AzureWebJobsSqlConnectionString" } ] diff --git a/tests/endtoend/sql_functions/sql_input2/__init__.py b/tests/endtoend/sql_functions/sql_input2/__init__.py new file mode 100644 index 000000000..a8e3c3b3b --- /dev/null +++ b/tests/endtoend/sql_functions/sql_input2/__init__.py @@ -0,0 +1,15 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import json +import azure.functions as func + + +def main(req: func.HttpRequest, products: func.SqlRowList) -> func.HttpResponse: + rows = list(map(lambda r: json.loads(r.to_json()), products)) + + return func.HttpResponse( + json.dumps(rows), + status_code=200, + mimetype="application/json" + ) diff --git a/tests/endtoend/sql_functions/sql_input2/function.json b/tests/endtoend/sql_functions/sql_input2/function.json new file mode 100644 index 000000000..07f8d7722 --- /dev/null +++ b/tests/endtoend/sql_functions/sql_input2/function.json @@ -0,0 +1,29 @@ +{ + "scriptFile": "__init__.py", + "bindings": [ + { + "authLevel": "anonymous", + "name": "req", + "type": "httpTrigger", + "direction": "in", + "methods": [ + "get" + ], + "route": "sql_input2/{productid}" + }, + { + "name": "$return", + "type": "http", + "direction": "out" + }, + { + "name": "products", + "type": "sql", + "direction": "in", + "commandText": "SELECT * FROM Products2 WHERE ProductId = @ProductId", + "commandType": "Text", + "parameters": "@ProductId={productid}", + "connectionStringSetting": "AzureWebJobsSqlConnectionString" + } + ] +} \ No newline at end of file diff --git a/tests/endtoend/sql_functions/sql_trigger/__init__.py b/tests/endtoend/sql_functions/sql_trigger/__init__.py new file mode 100644 index 000000000..c8e18173e --- /dev/null +++ b/tests/endtoend/sql_functions/sql_trigger/__init__.py @@ -0,0 +1,10 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +import json +import azure.functions as func + + +def main(changes, r: func.Out[func.SqlRow]) -> str: + row = func.SqlRow.from_dict(json.loads(changes)[0]["Item"]) + r.set(row) + return "OK" diff --git a/tests/endtoend/sql_functions/sql_trigger/function.json b/tests/endtoend/sql_functions/sql_trigger/function.json new file mode 100644 index 000000000..db68da83d --- /dev/null +++ b/tests/endtoend/sql_functions/sql_trigger/function.json @@ -0,0 +1,20 @@ +{ + "scriptFile": "__init__.py", + "disabled": false, + "bindings": [ + { + "name": "changes", + "type": "sqlTrigger", + "direction": "in", + "tableName": "dbo.Products", + "connectionStringSetting": "AzureWebJobsSqlConnectionString" + }, + { + "name": "r", + "type": "sql", + "direction": "out", + "commandText": "[dbo].[Products2]", + "connectionStringSetting": "AzureWebJobsSqlConnectionString" + } + ] +} \ No newline at end of file diff --git a/tests/endtoend/test_sql_functions.py b/tests/endtoend/test_sql_functions.py index 7d547715d..a0640c009 100644 --- a/tests/endtoend/test_sql_functions.py +++ b/tests/endtoend/test_sql_functions.py @@ -1,12 +1,11 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. import json -from unittest import skip +import time from tests.utils import testutils -@skip("Unskip when azure functions with SQL is released.") class TestSqlFunctions(testutils.WebHostTestCase): @classmethod @@ -14,13 +13,40 @@ def get_script_dir(cls): return testutils.E2E_TESTS_FOLDER / 'sql_functions' @testutils.retryable_test(3, 5) - def test_sql_output_and_input(self): - row = {"ProductId": 0, "Name": "test", "Cost": 100} + def test_sql_binding_trigger(self): + id = str(round(time.time())) + row = {"ProductId": id, "Name": "test", "Cost": 100} + # Insert a row into Products table using sql_output function r = self.webhost.request('POST', 'sql_output', data=json.dumps(row)) self.assertEqual(r.status_code, 201) - r = self.webhost.request('GET', 'sql_input') + # Check that the row was successfully inserted using sql_input function + r = self.webhost.request('GET', 'sql_input/' + id) self.assertEqual(r.status_code, 200) - expectedText = "[{\"ProductId\": 0, \"Name\": \"test\", \"Cost\": 100}]" + expectedText = "[{\"ProductId\": " + id + \ + ", \"Name\": \"test\", \"Cost\": 100}]" self.assertEqual(r.text, expectedText) + + # Check that the sql_trigger function has been triggered and + # the row has been inserted into Products2 table using sql_input2 + # function + max_retries = 10 + + for try_no in range(max_retries): + # Allow trigger to fire + time.sleep(2) + + try: + # Check that the trigger has fired + r = self.webhost.request('GET', 'sql_input2/' + id) + self.assertEqual(r.status_code, 200) + expectedText = "[{\"ProductId\": " + id + \ + ", \"Name\": \"test\", \"Cost\": 100}]" + self.assertEqual(r.text, expectedText) + + except AssertionError: + if try_no == max_retries - 1: + raise + else: + break diff --git a/tests/utils/constants.py b/tests/utils/constants.py index b5df573b3..eb567a7b4 100644 --- a/tests/utils/constants.py +++ b/tests/utils/constants.py @@ -29,7 +29,7 @@ + Version="3.0.534" />