Skip to content

Commit 473cd1e

Browse files
authored
Re-enable WorkerStatus report in Worker (#848)
* Add E2E tests * Test disabled scenario
1 parent 1fdc110 commit 473cd1e

File tree

4 files changed

+155
-1
lines changed

4 files changed

+155
-1
lines changed

azure_functions_worker/dispatcher.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ async def _handle__worker_init_request(self, req):
266266
constants.RAW_HTTP_BODY_BYTES: _TRUE,
267267
constants.TYPED_DATA_COLLECTION: _TRUE,
268268
constants.RPC_HTTP_BODY_ONLY: _TRUE,
269+
constants.WORKER_STATUS: _TRUE,
269270
constants.RPC_HTTP_TRIGGER_METADATA_REMOVED: _TRUE,
270271
constants.SHARED_MEMORY_DATA_TRANSFER: _TRUE,
271272
}
@@ -285,7 +286,7 @@ async def _handle__worker_status_request(self, req):
285286
# for host to judge scale decisions of out-of-proc languages.
286287
# Having log here will reduce the responsiveness of the worker.
287288
return protos.StreamingMessage(
288-
request_id=self.request_id,
289+
request_id=req.request_id,
289290
worker_status_response=protos.WorkerStatusResponse())
290291

291292
async def _handle__function_load_request(self, req):
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
# flake8: noqa
5+
import logging
6+
7+
import azure.functions as func
8+
9+
10+
def main(req: func.HttpRequest) -> func.HttpResponse:
11+
logging.info('Python HTTP trigger function processed a request.')
12+
13+
name = req.params.get('name')
14+
if not name:
15+
try:
16+
req_body = req.get_json()
17+
except ValueError:
18+
pass
19+
else:
20+
name = req_body.get('name')
21+
22+
if name:
23+
return func.HttpResponse(f"Hello, {name}. This HTTP triggered function executed successfully.")
24+
else:
25+
return func.HttpResponse(
26+
"This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
27+
status_code=200
28+
)
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": "function",
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+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
import os
4+
from unittest.mock import patch
5+
6+
import requests
7+
from azure_functions_worker import testutils
8+
9+
REQUEST_TIMEOUT_SEC = 5
10+
11+
12+
class TestHttpFunctions(testutils.WebHostTestCase):
13+
"""Test the native Http Trigger in the local webhost.
14+
15+
This test class will spawn a webhost from your <project_root>/build/webhost
16+
folder and replace the built-in Python with azure_functions_worker from
17+
your code base. Since the Http Trigger is a native suport from host, we
18+
don't need to setup any external resources.
19+
20+
Compared to the unittests/test_http_functions.py, this file is more focus
21+
on testing the E2E flow scenarios.
22+
"""
23+
def setUp(self):
24+
self._patch_environ = patch.dict('os.environ', os.environ.copy())
25+
self._patch_environ.start()
26+
27+
def tearDown(self):
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_function_index_page_should_return_ok(self):
36+
"""The index page of Azure Functions should return OK in any
37+
circumstances
38+
"""
39+
root_url = self.webhost._addr
40+
r = requests.get(root_url, timeout=REQUEST_TIMEOUT_SEC)
41+
self.assertTrue(r.ok)
42+
43+
@testutils.retryable_test(3, 5)
44+
def test_default_http_template_should_return_ok(self):
45+
"""Test if the default template of Http trigger in Python Function app
46+
will return OK
47+
"""
48+
r = self.webhost.request('GET', 'default_template',
49+
timeout=REQUEST_TIMEOUT_SEC)
50+
self.assertTrue(r.ok)
51+
52+
@testutils.retryable_test(3, 5)
53+
def test_default_http_template_should_accept_query_param(self):
54+
"""Test if the azure.functions SDK is able to deserialize query
55+
parameter from the default template
56+
"""
57+
r = self.webhost.request('GET', 'default_template',
58+
params={'name': 'query'},
59+
timeout=REQUEST_TIMEOUT_SEC)
60+
self.assertTrue(r.ok)
61+
self.assertEqual(
62+
r.content,
63+
b'Hello, query. This HTTP triggered function executed successfully.'
64+
)
65+
66+
@testutils.retryable_test(3, 5)
67+
def test_default_http_template_should_accept_body(self):
68+
"""Test if the azure.functions SDK is able to deserialize http body
69+
and pass it to default template
70+
"""
71+
r = self.webhost.request('POST', 'default_template',
72+
data='{ "name": "body" }'.encode('utf-8'),
73+
timeout=REQUEST_TIMEOUT_SEC)
74+
self.assertTrue(r.ok)
75+
self.assertEqual(
76+
r.content,
77+
b'Hello, body. This HTTP triggered function executed successfully.'
78+
)
79+
80+
@testutils.retryable_test(3, 5)
81+
def test_worker_status_endpoint_should_return_ok(self):
82+
"""Test if the worker status endpoint will trigger
83+
_handle__worker_status_request and sends a worker status response back
84+
to host
85+
"""
86+
root_url = self.webhost._addr
87+
health_check_url = f'{root_url}/admin/host/ping'
88+
r = requests.post(health_check_url,
89+
params={'checkHealth': '1'},
90+
timeout=REQUEST_TIMEOUT_SEC)
91+
self.assertTrue(r.ok)
92+
93+
@testutils.retryable_test(3, 5)
94+
def test_worker_status_endpoint_should_return_ok_when_disabled(self):
95+
"""Test if the worker status endpoint will trigger
96+
_handle__worker_status_request and sends a worker status response back
97+
to host
98+
"""
99+
os.environ['WEBSITE_PING_METRICS_SCALE_ENABLED'] = '0'
100+
root_url = self.webhost._addr
101+
health_check_url = f'{root_url}/admin/host/ping'
102+
r = requests.post(health_check_url,
103+
params={'checkHealth': '1'},
104+
timeout=REQUEST_TIMEOUT_SEC)
105+
self.assertTrue(r.ok)

0 commit comments

Comments
 (0)