Skip to content

test: add ServiceBus SDK tests #1678

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: dev
Choose a base branch
from
10 changes: 6 additions & 4 deletions eng/templates/jobs/ci-emulator-tests.yml
Original file line number Diff line number Diff line change
@@ -82,8 +82,9 @@ jobs:
- bash: |
python -m pytest -q -n auto --dist loadfile --reruns 4 --ignore=tests/emulator_tests/test_servicebus_functions.py tests/emulator_tests
env:
AzureWebJobsStorage: "UseDevelopmentStorage=true"
AzureWebJobsEventHubConnectionString: "Endpoint=sb://localhost;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;"
AzureWebJobsStorage: $(AzureWebJobsStorage)
AzureWebJobsEventHubConnectionString: $(AzureWebJobsEventHubConnectionString)
AZURE_STORAGE_CONNECTION_STRING: $(AZURE_STORAGE_CONNECTION_STRING)
displayName: "Running $(PYTHON_VERSION) Python Linux Emulator Tests"
- bash: |
# Stop and remove EventHub Emulator container to free up the port
@@ -97,6 +98,7 @@ jobs:
- bash: |
python -m pytest -q -n auto --dist loadfile --reruns 4 tests/emulator_tests/test_servicebus_functions.py
env:
AzureWebJobsStorage: "UseDevelopmentStorage=true"
AzureWebJobsServiceBusConnectionString: "Endpoint=sb://localhost;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;"
AzureWebJobsStorage: $(AzureWebJobsStorage)
AzureWebJobsServiceBusConnectionString: $(AzureWebJobsServiceBusConnectionString)
AzureWebJobsServiceBusSDKConnectionString: $(AzureWebJobsServiceBusSDKConnectionString)
displayName: "Running $(PYTHON_VERSION) Python ServiceBus Linux Emulator Tests"
1 change: 1 addition & 0 deletions eng/templates/jobs/ci-unit-tests.yml
Original file line number Diff line number Diff line change
@@ -55,4 +55,5 @@ jobs:
condition: and(eq(variables.isSdkRelease, false), eq(variables.isExtensionsRelease, false), eq(variables['USETESTPYTHONSDK'], false), eq(variables['USETESTPYTHONEXTENSIONS'], false))
env:
PYTHON_VERSION: $(PYTHON_VERSION)
AZURE_STORAGE_CONNECTION_STRING: $(AZURE_STORAGE_CONNECTION_STRING)

2 changes: 1 addition & 1 deletion eng/templates/official/jobs/ci-e2e-tests.yml
Original file line number Diff line number Diff line change
@@ -150,7 +150,7 @@ jobs:
Write-Host "skipTest: $(skipTest)"
displayName: 'Display skipTest variable'
- bash: |
python -m pytest -q -n auto --dist loadfile --reruns 4 --cov=./azure_functions_worker --cov-report xml --cov-branch --cov-append tests/endtoend tests/extension_tests/deferred_bindings_tests tests/extension_tests/http_v2_tests
python -m pytest -q -n auto --dist loadfile --reruns 4 --cov=./azure_functions_worker --cov-report xml --cov-branch --cov-append tests/endtoend
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for the extension_tests folder anymore -- blob SDK bindings tests are moved to emulators folder, and HttpV2 moved to E2E

env:
AzureWebJobsStorage: $(STORAGE_CONNECTION)
AzureWebJobsCosmosDBConnectionString: $(COSMOSDB_CONNECTION)
1 change: 1 addition & 0 deletions eng/templates/utils/variables.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
variables:
- group: python-emulator-resources
- name: isSdkRelease
value: $[startsWith(variables['Build.SourceBranch'], 'refs/heads/sdk/')]
- name: isExtensionsRelease
6 changes: 4 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -79,7 +79,8 @@ dev = [
"numpy",
"pre-commit",
"invoke",
"cryptography"
"cryptography",
"jsonpickle"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added jsonpickle to help with the SB tests. Majority of the properties of the ServiceBusReceivedMessage were not JSON-serializable, and I wanted to keep the same general test structure as the current SB tests

]
test-http-v2 = [
"azurefunctions-extensions-http-fastapi==1.0.0b2",
@@ -88,7 +89,8 @@ test-http-v2 = [
]
test-deferred-bindings = [
"azurefunctions-extensions-bindings-blob==1.0.0b3",
"azurefunctions-extensions-bindings-eventhub==1.0.0b1"
"azurefunctions-extensions-bindings-eventhub==1.0.0b1",
"azurefunctions-extensions-bindings-servicebus==1.0.0b1"
]

[build-system]
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
@app.function_name(name="put_bc_trigger")
@app.blob_output(arg_name="file",
path="python-worker-tests/test-blobclient-trigger.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.route(route="put_bc_trigger")
def put_bc_trigger(req: func.HttpRequest, file: func.Out[str]) -> str:
file.set(req.get_body())
@@ -21,10 +21,10 @@ def put_bc_trigger(req: func.HttpRequest, file: func.Out[str]) -> str:
@app.function_name(name="bc_blob_trigger")
@app.blob_trigger(arg_name="client",
path="python-worker-tests/test-blobclient-trigger.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.blob_output(arg_name="$return",
path="python-worker-tests/test-blobclient-triggered.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
def bc_blob_trigger(client: blob.BlobClient) -> str:
blob_properties = client.get_blob_properties()
file = client.download_blob(encoding='utf-8').readall()
@@ -38,7 +38,7 @@ def bc_blob_trigger(client: blob.BlobClient) -> str:
@app.function_name(name="get_bc_blob_triggered")
@app.blob_input(arg_name="client",
path="python-worker-tests/test-blobclient-triggered.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.route(route="get_bc_blob_triggered")
def get_bc_blob_triggered(req: func.HttpRequest,
client: blob.BlobClient) -> str:
@@ -48,7 +48,7 @@ def get_bc_blob_triggered(req: func.HttpRequest,
@app.function_name(name="put_cc_trigger")
@app.blob_output(arg_name="file",
path="python-worker-tests/test-containerclient-trigger.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.route(route="put_cc_trigger")
def put_cc_trigger(req: func.HttpRequest, file: func.Out[str]) -> str:
file.set(req.get_body())
@@ -58,10 +58,10 @@ def put_cc_trigger(req: func.HttpRequest, file: func.Out[str]) -> str:
@app.function_name(name="cc_blob_trigger")
@app.blob_trigger(arg_name="client",
path="python-worker-tests/test-containerclient-trigger.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.blob_output(arg_name="$return",
path="python-worker-tests/test-containerclient-triggered.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
def cc_blob_trigger(client: blob.ContainerClient) -> str:
container_properties = client.get_container_properties()
file = client.download_blob("test-containerclient-trigger.txt",
@@ -75,7 +75,7 @@ def cc_blob_trigger(client: blob.ContainerClient) -> str:
@app.function_name(name="get_cc_blob_triggered")
@app.blob_input(arg_name="client",
path="python-worker-tests/test-containerclient-triggered.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.route(route="get_cc_blob_triggered")
def get_cc_blob_triggered(req: func.HttpRequest,
client: blob.ContainerClient) -> str:
@@ -86,7 +86,7 @@ def get_cc_blob_triggered(req: func.HttpRequest,
@app.function_name(name="put_ssd_trigger")
@app.blob_output(arg_name="file",
path="python-worker-tests/test-ssd-trigger.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.route(route="put_ssd_trigger")
def put_ssd_trigger(req: func.HttpRequest, file: func.Out[str]) -> str:
file.set(req.get_body())
@@ -96,10 +96,10 @@ def put_ssd_trigger(req: func.HttpRequest, file: func.Out[str]) -> str:
@app.function_name(name="ssd_blob_trigger")
@app.blob_trigger(arg_name="stream",
path="python-worker-tests/test-ssd-trigger.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.blob_output(arg_name="$return",
path="python-worker-tests/test-ssd-triggered.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
def ssd_blob_trigger(stream: blob.StorageStreamDownloader) -> str:
# testing chunking
file = ""
@@ -113,7 +113,7 @@ def ssd_blob_trigger(stream: blob.StorageStreamDownloader) -> str:
@app.function_name(name="get_ssd_blob_triggered")
@app.blob_input(arg_name="stream",
path="python-worker-tests/test-ssd-triggered.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.route(route="get_ssd_blob_triggered")
def get_ssd_blob_triggered(req: func.HttpRequest,
stream: blob.StorageStreamDownloader) -> str:
@@ -124,7 +124,7 @@ def get_ssd_blob_triggered(req: func.HttpRequest,
@app.route(route="get_bc_bytes")
@app.blob_input(arg_name="client",
path="python-worker-tests/test-blob-extension-bytes.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
def get_bc_bytes(req: func.HttpRequest, client: blob.BlobClient) -> str:
return client.download_blob(encoding='utf-8').readall()

@@ -133,7 +133,7 @@ def get_bc_bytes(req: func.HttpRequest, client: blob.BlobClient) -> str:
@app.route(route="get_cc_bytes")
@app.blob_input(arg_name="client",
path="python-worker-tests/test-blob-extension-bytes.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
def get_cc_bytes(req: func.HttpRequest,
client: blob.ContainerClient) -> str:
return client.download_blob("test-blob-extension-bytes.txt",
@@ -144,7 +144,7 @@ def get_cc_bytes(req: func.HttpRequest,
@app.route(route="get_ssd_bytes")
@app.blob_input(arg_name="stream",
path="python-worker-tests/test-blob-extension-bytes.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
def get_ssd_bytes(req: func.HttpRequest,
stream: blob.StorageStreamDownloader) -> str:
return stream.readall().decode('utf-8')
@@ -154,7 +154,7 @@ def get_ssd_bytes(req: func.HttpRequest,
@app.route(route="get_bc_str")
@app.blob_input(arg_name="client",
path="python-worker-tests/test-blob-extension-str.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
def get_bc_str(req: func.HttpRequest, client: blob.BlobClient) -> str:
return client.download_blob(encoding='utf-8').readall()

@@ -163,7 +163,7 @@ def get_bc_str(req: func.HttpRequest, client: blob.BlobClient) -> str:
@app.route(route="get_cc_str")
@app.blob_input(arg_name="client",
path="python-worker-tests",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
def get_cc_str(req: func.HttpRequest, client: blob.ContainerClient) -> str:
return client.download_blob("test-blob-extension-str.txt",
encoding='utf-8').readall()
@@ -173,7 +173,7 @@ def get_cc_str(req: func.HttpRequest, client: blob.ContainerClient) -> str:
@app.route(route="get_ssd_str")
@app.blob_input(arg_name="stream",
path="python-worker-tests/test-blob-extension-str.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
def get_ssd_str(req: func.HttpRequest, stream: blob.StorageStreamDownloader) -> str:
return stream.readall().decode('utf-8')

@@ -183,11 +183,11 @@ def get_ssd_str(req: func.HttpRequest, stream: blob.StorageStreamDownloader) ->
@app.blob_input(arg_name="client",
path="python-worker-tests/test-blob-extension-str.txt",
data_type="STRING",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.blob_input(arg_name="blob",
path="python-worker-tests/test-blob-extension-str.txt",
data_type="STRING",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
def bc_and_inputstream_input(req: func.HttpRequest, client: blob.BlobClient,
blob: func.InputStream) -> str:
output_msg = ""
@@ -202,11 +202,11 @@ def bc_and_inputstream_input(req: func.HttpRequest, client: blob.BlobClient,
@app.blob_input(arg_name="blob",
path="python-worker-tests/test-blob-extension-str.txt",
data_type="STRING",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.blob_input(arg_name="client",
path="python-worker-tests/test-blob-extension-str.txt",
data_type="STRING",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
def inputstream_and_bc_input(req: func.HttpRequest, blob: func.InputStream,
client: blob.BlobClient) -> str:
output_msg = ""
@@ -221,7 +221,7 @@ def inputstream_and_bc_input(req: func.HttpRequest, blob: func.InputStream,
@app.blob_input(arg_name="file",
path="python-worker-tests/test-blob-extension-str.txt",
data_type="STRING",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
def type_undefined(req: func.HttpRequest, file) -> str:
assert not isinstance(file, blob.BlobClient)
assert not isinstance(file, blob.ContainerClient)
@@ -232,7 +232,7 @@ def type_undefined(req: func.HttpRequest, file) -> str:
@app.function_name(name="put_blob_str")
@app.blob_output(arg_name="file",
path="python-worker-tests/test-blob-extension-str.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.route(route="put_blob_str")
def put_blob_str(req: func.HttpRequest, file: func.Out[str]) -> str:
file.set(req.get_body())
@@ -242,7 +242,7 @@ def put_blob_str(req: func.HttpRequest, file: func.Out[str]) -> str:
@app.function_name(name="put_blob_bytes")
@app.blob_output(arg_name="file",
path="python-worker-tests/test-blob-extension-bytes.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.route(route="put_blob_bytes")
def put_blob_bytes(req: func.HttpRequest, file: func.Out[bytes]) -> str:
file.set(req.get_body())
@@ -252,7 +252,7 @@ def put_blob_bytes(req: func.HttpRequest, file: func.Out[bytes]) -> str:
@app.function_name(name="blob_cache")
@app.blob_input(arg_name="cachedClient",
path="python-worker-tests/test-blobclient-triggered.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.route(route="blob_cache")
def blob_cache(req: func.HttpRequest,
cachedClient: blob.BlobClient) -> str:
@@ -262,7 +262,7 @@ def blob_cache(req: func.HttpRequest,
@app.function_name(name="blob_cache2")
@app.blob_input(arg_name="cachedClient",
path="python-worker-tests/test-blobclient-triggered.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.route(route="blob_cache2")
def blob_cache2(req: func.HttpRequest,
cachedClient: blob.BlobClient) -> func.HttpResponse:
@@ -272,10 +272,10 @@ def blob_cache2(req: func.HttpRequest,
@app.function_name(name="blob_cache3")
@app.blob_input(arg_name="cachedClient",
path="python-worker-tests/test-blobclient-triggered.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.blob_input(arg_name="cachedClient2",
path="python-worker-tests/test-blobclient-triggered.txt",
connection="AzureWebJobsStorage")
connection="AZURE_STORAGE_CONNECTION_STRING")
@app.route(route="blob_cache3")
def blob_cache3(req: func.HttpRequest,
cachedClient: blob.BlobClient,
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import json
import jsonpickle

import azure.functions as func
import azurefunctions.extensions.bindings.servicebus as sb

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)


@app.route(route="put_message_sdk")
@app.service_bus_queue_output(
arg_name="msg",
connection="AzureWebJobsServiceBusSDKConnectionString",
queue_name="testqueue")
def put_message_sdk(req: func.HttpRequest, msg: func.Out[str]):
msg.set(req.get_body().decode('utf-8'))
return 'OK'


@app.route(route="get_servicebus_triggered_sdk")
@app.blob_input(arg_name="file",
path="python-worker-tests/test-servicebus-sdk-triggered.txt",
connection="AzureWebJobsStorage")
def get_servicebus_triggered_sdk(req: func.HttpRequest,
file: func.InputStream) -> str:
return func.HttpResponse(
file.read().decode('utf-8'), mimetype='application/json')


@app.service_bus_queue_trigger(
arg_name="msg",
connection="AzureWebJobsServiceBusSDKConnectionString",
queue_name="testqueue")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a test for SB topics?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the extension support topics?

@app.blob_output(arg_name="$return",
path="python-worker-tests/test-servicebus-sdk-triggered.txt",
connection="AzureWebJobsStorage")
def servicebus_trigger_sdk(msg: sb.ServiceBusReceivedMessage) -> str:
msg_json = jsonpickle.encode(msg)
body_json = jsonpickle.encode(msg.body)
enqueued_time_json = jsonpickle.encode(msg.enqueued_time_utc)
lock_token_json = jsonpickle.encode(msg.lock_token)
result = json.dumps({
'message': msg_json,
'body': body_json,
'enqueued_time_utc': enqueued_time_json,
'lock_token': lock_token_json,
'message_id': msg.message_id,
'sequence_number': msg.sequence_number
})

return result


@app.route(route="put_message_sdk_topic")
@app.service_bus_topic_output(arg_name="msg",
connection="AzureWebJobsServiceBusSDKConnectionString",
topic_name="testtopic")
def put_message_sdk_topic(req: func.HttpRequest, msg: func.Out[str]):
msg.set(req.get_body().decode('utf-8'))
return 'OK'


@app.route(route="get_servicebus_triggered_sdk_topic")
@app.blob_input(arg_name="file",
path="python-worker-tests/test-servicebus-sdk-triggered-topic.txt",
connection="AzureWebJobsStorage")
def get_servicebus_triggered_sdk_topic(req: func.HttpRequest,
file: func.InputStream) -> str:
return func.HttpResponse(
file.read().decode('utf-8'), mimetype='application/json')


@app.service_bus_topic_trigger(arg_name="msg",
topic_name="testtopic",
connection="AzureWebJobsServiceBusSDKConnectionString",
subscription_name="testsub")
@app.blob_output(arg_name="$return",
path="python-worker-tests/test-servicebus-sdk-triggered-topic.txt",
connection="AzureWebJobsStorage")
def servicebus_trigger_sdk_topic(msg: sb.ServiceBusReceivedMessage) -> str:
msg_json = jsonpickle.encode(msg)
body_json = jsonpickle.encode(msg.body)
enqueued_time_json = jsonpickle.encode(msg.enqueued_time_utc)
lock_token_json = jsonpickle.encode(msg.lock_token)
result = json.dumps({
'message': msg_json,
'body': body_json,
'enqueued_time_utc': enqueued_time_json,
'lock_token': lock_token_json,
'message_id': msg.message_id,
'sequence_number': msg.sequence_number
})

return result
Loading