Skip to content

Commit 774ecea

Browse files
authored
Merge branch 'dev' into gaaguiar/get_bindings_revamp
2 parents bf61cb7 + c403eab commit 774ecea

File tree

7 files changed

+175
-48
lines changed

7 files changed

+175
-48
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ Here is the current status of Python in Azure Functions:
1111

1212
What are the supported Python versions?
1313

14-
| Azure Functions Runtime | Python 3.6 | Python 3.7 | Python 3.8 | Python 3.9 | Python 3.10 |
15-
|----------------------------------|------------|------------|------------|------------|-------------|
16-
| Azure Functions 2.0 (deprecated) ||| - | - | - |
17-
| Azure Functions 3.0 ||||| - |
18-
| Azure Functions 4.0 | - |||| coming soon |
14+
| Azure Functions Runtime | Python 3.6 | Python 3.7 | Python 3.8 | Python 3.9 | Python 3.10 | Python 3.11 |
15+
|----------------------------------|------------|------------|------------|------------|-------------|-------------|
16+
| Azure Functions 2.0 (deprecated) ||| - | - | - | - |
17+
| Azure Functions 3.0 (deprecated) |||| | - | - |
18+
| Azure Functions 4.0 | - |||| | coming soon |
1919

2020
For information about Azure Functions Runtime, please refer to [Azure Functions runtime versions overview](https://docs.microsoft.com/en-us/azure/azure-functions/functions-versions) page.
2121

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
from datetime import datetime
4+
# flake8: noqa
5+
import azure.functions as func
6+
import time
7+
8+
9+
def main(req: func.HttpRequest) -> func.HttpResponse:
10+
time.sleep(1)
11+
12+
current_time = datetime.now().strftime("%H:%M:%S")
13+
return func.HttpResponse(f"{current_time}")
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"scriptFile": "__init__.py",
3+
"bindings": [
4+
{
5+
"authLevel": "anonymous",
6+
"type": "httpTrigger",
7+
"direction": "in",
8+
"name": "req",
9+
"methods": [
10+
"get",
11+
"post"
12+
]
13+
},
14+
{
15+
"type": "http",
16+
"direction": "out",
17+
"name": "$return"
18+
}
19+
]
20+
}

tests/endtoend/http_functions/http_functions_stein/function_app.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# Copyright (c) Microsoft Corporation. All rights reserved.
22
# Licensed under the MIT License.
33

4+
from datetime import datetime
45
import logging
6+
import time
57

68
import azure.functions as func
79

@@ -32,3 +34,11 @@ def default_template(req: func.HttpRequest) -> func.HttpResponse:
3234
" personalized response.",
3335
status_code=200
3436
)
37+
38+
39+
@app.route(route="http_func")
40+
def http_func(req: func.HttpRequest) -> func.HttpResponse:
41+
time.sleep(1)
42+
43+
current_time = datetime.now().strftime("%H:%M:%S")
44+
return func.HttpResponse(f"{current_time}")

tests/endtoend/test_multi_worker_functions.py

Lines changed: 0 additions & 43 deletions
This file was deleted.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
import os
4+
from threading import Thread
5+
from unittest.mock import patch
6+
from datetime import datetime
7+
from tests.utils import testutils
8+
9+
10+
class TestPythonThreadpoolThreadCount(testutils.WebHostTestCase):
11+
""" Test the Http Trigger with setting up the python threadpool thread
12+
count to 2. this test will check if both requests should be processed
13+
at the same time. this file is more focus on testing the E2E flow
14+
scenarios.
15+
"""
16+
17+
@classmethod
18+
def setUpClass(cls):
19+
os_environ = os.environ.copy()
20+
os_environ['PYTHON_THREADPOOL_THREAD_COUNT'] = '2'
21+
cls._patch_environ = patch.dict('os.environ', os_environ)
22+
cls._patch_environ.start()
23+
super().setUpClass()
24+
25+
def tearDown(self):
26+
super().tearDown()
27+
self._patch_environ.stop()
28+
29+
@classmethod
30+
def get_script_dir(cls):
31+
return testutils.E2E_TESTS_FOLDER / 'http_functions'
32+
33+
@testutils.retryable_test(3, 5)
34+
def test_http_func_with_thread_count(self):
35+
response = [None, None]
36+
37+
def http_req(res_num):
38+
r = self.webhost.request('GET', 'http_func')
39+
self.assertTrue(r.ok)
40+
response[res_num] = datetime.strptime(
41+
r.content.decode("utf-8"), "%H:%M:%S")
42+
43+
# creating 2 different threads to send HTTP request
44+
thread1 = Thread(target=http_req, args=(0,))
45+
thread2 = Thread(target=http_req, args=(1,))
46+
thread1.start()
47+
thread2.start()
48+
thread1.join()
49+
thread2.join()
50+
"""function execution time difference between both HTTP request
51+
should be less than 1 since both the request should be processed at
52+
the same time because PYTHON_THREADPOOL_THREAD_COUNT is 2.
53+
"""
54+
time_diff_in_seconds = abs((response[0] - response[1]).total_seconds())
55+
self.assertTrue(time_diff_in_seconds < 1)
56+
57+
58+
class TestPythonThreadpoolThreadCountStein(TestPythonThreadpoolThreadCount):
59+
60+
@classmethod
61+
def get_script_dir(cls):
62+
return testutils.E2E_TESTS_FOLDER / 'http_functions' / \
63+
'http_functions_stein'
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
import os
4+
from threading import Thread
5+
from unittest.mock import patch
6+
from datetime import datetime
7+
from tests.utils import testutils
8+
9+
10+
class TestWorkerProcessCount(testutils.WebHostTestCase):
11+
"""Test the Http Trigger with setting up the python worker process count
12+
to 2. this test will check if both requests should be processed at the
13+
same time. this file is more focused on testing the E2E flow scenario for
14+
FUNCTIONS_WORKER_PROCESS_COUNT feature.
15+
"""
16+
17+
@classmethod
18+
def setUpClass(cls):
19+
os_environ = os.environ.copy()
20+
os_environ['PYTHON_THREADPOOL_THREAD_COUNT'] = '1'
21+
os_environ['FUNCTIONS_WORKER_PROCESS_COUNT'] = '2'
22+
cls._patch_environ = patch.dict('os.environ', os_environ)
23+
cls._patch_environ.start()
24+
super().setUpClass()
25+
26+
def tearDown(self):
27+
super().tearDown()
28+
self._patch_environ.stop()
29+
30+
@classmethod
31+
def get_script_dir(cls):
32+
return testutils.E2E_TESTS_FOLDER / 'http_functions'
33+
34+
@testutils.retryable_test(3, 5)
35+
def test_http_func_with_worker_process_count_2(self):
36+
response = [None, None]
37+
38+
def http_req(res_num):
39+
r = self.webhost.request('GET', 'http_func')
40+
self.assertTrue(r.ok)
41+
response[res_num] = datetime.strptime(
42+
r.content.decode("utf-8"), "%H:%M:%S")
43+
44+
# creating 2 different threads to send HTTP request
45+
thread1 = Thread(target=http_req, args=(0,))
46+
thread2 = Thread(target=http_req, args=(1,))
47+
thread1.start()
48+
thread2.start()
49+
thread1.join()
50+
thread2.join()
51+
'''function execution time difference between both HTTP request
52+
should be less than 1 since both request should be processed at the
53+
same time because FUNCTIONS_WORKER_PROCESS_COUNT is 2.
54+
'''
55+
time_diff_in_seconds = abs((response[0] - response[1]).total_seconds())
56+
self.assertTrue(time_diff_in_seconds < 1)
57+
58+
59+
class TestWorkerProcessCountStein(TestWorkerProcessCount):
60+
61+
@classmethod
62+
def get_script_dir(cls):
63+
return testutils.E2E_TESTS_FOLDER / 'http_functions' /\
64+
'http_functions_stein'

0 commit comments

Comments
 (0)