@@ -2,35 +2,37 @@ name: Throughput testing workflow
2
2
3
3
on :
4
4
workflow_dispatch :
5
- pull_request :
6
- branches : [ dev ]
7
-
5
+ inputs :
6
+ profiling_sampling_rate :
7
+ description : ' Profiling sampling rate (tps)'
8
+ required : false
9
+ default : ' 500'
10
+ test_to_run :
11
+ description : ' List of perf tests to run'
12
+ required : false
13
+ default : SyncHelloWorld
14
+ issue_comment :
15
+ types : [created]
8
16
env :
9
17
TESTS_DIR_PATH : " .ci/perf_tests/k6scripts/"
10
- PYTHON_VERSION : " 3.8"
18
+ PYTHON_VERSION : " 3.10"
19
+ PYTHON_FUNCTION_PROFILING_STORAGE_ACCT : " azpyfuncpipelinestorage"
11
20
PORT : 8000
12
21
13
22
jobs :
14
23
build :
24
+ if : ${{ github.event_name == 'workflow_dispatch' || github.event.issue.pull_request && contains(github.event.comment.body, '/profile') }}
15
25
runs-on : ubuntu-latest
16
26
strategy :
17
27
fail-fast : false
18
28
matrix :
19
- test_to_run : [ SyncHttpTriggerHelloWorld ]
29
+ test_to_run : ['${{ github.event.inputs.test_to_run }}' ]
20
30
steps :
21
31
- uses : actions/checkout@v2
22
32
- name : Set up Python ${{ env.PYTHON_VERSION }}
23
33
uses : actions/setup-python@v2
24
34
with :
25
35
python-version : ${{ env.PYTHON_VERSION }}
26
- - name : Set up Dotnet 2.x
27
- uses : actions/setup-dotnet@v1
28
- with :
29
- dotnet-version : ' 3.1.405'
30
- - name : Set up Dotnet 6.x
31
- uses : actions/setup-dotnet@v1
32
- with :
33
- dotnet-version : ' 6.x'
34
36
- name : Setup k6 for throughput testing
35
37
run : |
36
38
cd $GITHUB_WORKSPACE
@@ -47,13 +49,76 @@ jobs:
47
49
python setup.py extension
48
50
- name : Build and Run the Docker image
49
51
run : |
52
+ echo "Building Docker image with Python version ${{ env.PYTHON_VERSION }}"
50
53
docker build --build-arg PYTHON_VERSION=${{ env.PYTHON_VERSION }} --file .ci/perf_tests/dockerfiles/perf_tests.Dockerfile --tag perfimage:latest .
51
- docker run -d --shm-size="2g" --env FUNCTIONS_WORKER_RUNTIME_VERSION=${{ env.PYTHON_VERSION }} -p ${PORT}:80 -v $GITHUB_WORKSPACE/azure_functions_worker:/azure-functions-host/workers/python/${{ env.PYTHON_VERSION }}/LINUX/X64/azure_functions_worker perfimage:latest
54
+
55
+ echo "Running Docker container..."
56
+ container_id=$(docker run -d --privileged --env FUNCTIONS_WORKER_RUNTIME_VERSION=${{ env.PYTHON_VERSION }} -p ${PORT}:80 -v $GITHUB_WORKSPACE/azure_functions_worker:/azure-functions-host/workers/python/${{ env.PYTHON_VERSION }}/LINUX/X64/azure_functions_worker perfimage:latest)
52
57
sleep 10 # host needs some time to start.
58
+ echo "Container ID is $container_id"
59
+
60
+ echo "Fetching Docker container logs..."
61
+ docker logs $container_id
62
+ worker_pid=$(docker exec $container_id sh -c "ps aux | grep '[p]ython'" | awk '{print $2}')
63
+ echo "Python worker process id is $worker_pid"
64
+
65
+ echo "container_id=$container_id" >> $GITHUB_ENV
66
+ echo "worker_pid=$worker_pid" >> $GITHUB_ENV
67
+
53
68
- name : Validate if the functions are now running
54
69
run : |
55
70
curl --get http://localhost:${PORT}/api/${{ matrix.test_to_run }}
71
+
72
+ - name : Start py-spy in the background
73
+ run : |
74
+ docker exec $container_id sh -c "pip install py-spy"
75
+ docker exec $container_id sh -c "mkdir /home/profiling_reports"
76
+ profiling_sampling_rate=${{ github.event.inputs.profiling_sampling_rate }}
77
+ # report_name="${GITHUB_REF#refs/heads/}_${{ github.run_id }}.svg"
78
+ report_name="${{ github.run_id }}.svg"
79
+ docker exec -d $container_id sh -c "RUST_BACKTRACE=1 py-spy record -p $worker_pid -o /home/profiling_reports/$report_name -f flamegraph --idle --nonblocking --rate $profiling_sampling_rate > /home/site/wwwroot/py-spy.log 2>&1 &"
80
+ sleep 2 # Give it a moment to start
81
+ py_spy_id=$(docker exec $container_id sh -c "ps aux | grep '[p]y-spy record'" | awk '{print $2}')
82
+
83
+ echo "py_spy_id=$py_spy_id" >> $GITHUB_ENV
84
+ echo "report_name=$report_name" >> $GITHUB_ENV
85
+
56
86
- name : Run Throughput tests
57
87
run : |
58
88
chmod 755 .ci/perf_tests/run-perftests.sh
59
89
.ci/perf_tests/run-perftests.sh localhost $PORT ${{ env.TESTS_DIR_PATH }} ${{ matrix.test_to_run }}
90
+
91
+ - name : Stop profiling and generate report
92
+ run : |
93
+ echo "Tests completed, terminating py-spy..."
94
+ docker exec $container_id cat /home/site/wwwroot/py-spy.log
95
+ docker exec $container_id sh -c "kill -2 $py_spy_id"
96
+ sleep 2
97
+
98
+ mkdir profiling_reports
99
+ chmod 777 profiling_reports
100
+ docker cp $container_id:/home/profiling_reports/$report_name profiling_reports
101
+
102
+ - name : Upload SVG to Azure Blob Storage
103
+ uses :
bacongobbler/[email protected]
104
+ with :
105
+ source_dir : ' profiling_reports' # Directory containing the $report_name file
106
+ container_name : ' profiling'
107
+ connection_string : ${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}
108
+ sync : ' false'
109
+
110
+ - name : Output Blob URL
111
+ run : |
112
+ blob_url="https://${{ env.PYTHON_FUNCTION_PROFILING_STORAGE_ACCT }}.blob.core.windows.net/profiling/${{ env.report_name }}"
113
+ echo "You can view the Blob at: $blob_url"
114
+
115
+ - name : Upload profiling result to artifact
116
+ uses : actions/upload-artifact@v2
117
+ with :
118
+ name : py-spy-output
119
+ path : ' profiling_reports/${{ env.report_name }}'
120
+
121
+ - name : Create Artifact Link
122
+ run : |
123
+ echo "You can download the SVG artifact from the Actions run page."
124
+ echo "Link to the Actions run page: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
0 commit comments