Skip to content

Commit a5e25d4

Browse files
authored
Merge pull request #1105 from cmu-delphi/release/delphi-epidata-0.4.7
Release Delphi Epidata 0.4.7
2 parents 15da9b4 + b5e9bcb commit a5e25d4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+343
-3156
lines changed

.bumpversion.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.4.6
2+
current_version = 0.4.7
33
commit = False
44
tag = False
55

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
name: Performance testing
2+
3+
# Run when a PR comment is created (issues and PRs are considered the same entity in the GitHub API)
4+
on:
5+
issue_comment:
6+
types: [created]
7+
8+
# Add some extra perms to comment on a PR
9+
permissions:
10+
pull-requests: write
11+
contents: read
12+
13+
jobs:
14+
run-perftests:
15+
# Make sure 1. this is a PR, not an issue 2. it contains "/run performance test" anywhere in the body
16+
if: github.event.issue.pull_request && contains(github.event.comment.body, '/run performance test')
17+
runs-on: ubuntu-latest
18+
outputs:
19+
request_count: ${{ steps.output.outputs.request_count }}
20+
failure_count: ${{ steps.output.outputs.failure_count }}
21+
med_time: ${{ steps.output.outputs.med_time }}
22+
avg_time: ${{ steps.output.outputs.avg_time }}
23+
min_time: ${{ steps.output.outputs.min_time }}
24+
max_time: ${{ steps.output.outputs.max_time }}
25+
requests_per_sec: ${{ steps.output.outputs.requests_per_sec }}
26+
steps:
27+
- name: Set up WireGuard
28+
uses: egor-tensin/[email protected]
29+
with:
30+
endpoint: '${{ secrets.WG_PERF_ENDPOINT }}'
31+
endpoint_public_key: '${{ secrets.WG_PERF_ENDPOINT_PUBLIC_KEY }}'
32+
ips: '${{ secrets.WG_PERF_IPS }}'
33+
allowed_ips: '${{ secrets.WG_PERF_ALLOWED_IPS }}'
34+
private_key: '${{ secrets.WG_PERF_PRIVATE_KEY }}'
35+
- name: Check out repository
36+
uses: actions/checkout@v3
37+
# Previous step checks out default branch, so we check out the pull request's branch
38+
- name: Switch to PR branch
39+
run: |
40+
hub pr checkout ${{ github.event.issue.number }}
41+
env:
42+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43+
- name: Set up repository # mimics install.sh in the README except that delphi is cloned from the PR rather than main
44+
run: |
45+
cd ..
46+
mkdir -p driver/repos/delphi
47+
cd driver/repos/delphi
48+
git clone https://github.com/cmu-delphi/operations
49+
git clone https://github.com/cmu-delphi/utils
50+
git clone https://github.com/cmu-delphi/flu-contest
51+
git clone https://github.com/cmu-delphi/nowcast
52+
cd ../../
53+
54+
cd ..
55+
cp -R delphi-epidata driver/repos/delphi/delphi-epidata
56+
cd -
57+
58+
ln -s repos/delphi/delphi-epidata/dev/local/Makefile
59+
- name: Build & run epidata
60+
run: |
61+
cd ../driver
62+
sudo make web sql="${{ secrets.DB_CONN_STRING }}"
63+
- name: Check out delphi-admin
64+
uses: actions/checkout@v3
65+
with:
66+
repository: cmu-delphi/delphi-admin
67+
token: ${{ secrets.CMU_DELPHI_DEPLOY_MACHINE_PAT }}
68+
path: delphi-admin
69+
- name: Build & run Locust
70+
continue-on-error: true # sometimes ~2-5 queries fail, we shouldn't end the run if that's the case
71+
run: |
72+
cd delphi-admin/load-testing/locust
73+
docker build -t locust .
74+
export CSV=v4-requests-small.csv
75+
touch output_stats.csv && chmod 666 output_stats.csv
76+
touch output_stats_history.csv && chmod 666 output_stats_history.csv
77+
touch output_failures.csv && chmod 666 output_failures.csv
78+
touch output_exceptions.csv && chmod 666 output_exceptions.csv
79+
docker run --net=host -v $PWD:/mnt/locust -e CSV="/mnt/locust/${CSV}" locust -f /mnt/locust/v4.py --host http://127.0.0.1:10080/ --users 10 --spawn-rate 1 --headless -i "$(cat ${CSV} | wc -l)" --csv=/mnt/locust/output
80+
- name: Produce output for summary
81+
id: output
82+
uses: jannekem/run-python-script-action@v1
83+
with:
84+
script: |
85+
import os
86+
87+
def write_string(name, value):
88+
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
89+
print(f'{name}={value}', file=fh)
90+
91+
def write_float(name, value):
92+
write_string(name, "{:.2f}".format(float(value)))
93+
94+
with open("delphi-admin/load-testing/locust/output_stats.csv", "r", encoding="utf-8", errors="ignore") as scraped:
95+
final_line = scraped.readlines()[-1].split(",")
96+
write_string('request_count', final_line[2])
97+
write_string('failure_count', final_line[3])
98+
write_float('med_time', final_line[4])
99+
write_float('avg_time', final_line[5])
100+
write_float('min_time', final_line[6])
101+
write_float('max_time', final_line[7])
102+
write_float('requests_per_sec', final_line[9])
103+
104+
- name: Archive results as artifacts
105+
uses: actions/upload-artifact@v3
106+
with:
107+
name: locust-output
108+
path: |
109+
delphi-admin/load-testing/locust/output_*.csv
110+
111+
comment-success:
112+
runs-on: ubuntu-latest
113+
if: success()
114+
needs: run-perftests
115+
steps:
116+
- name: Comment run results
117+
env:
118+
GITHUB_WORKFLOW_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
119+
uses: actions/github-script@v5
120+
with:
121+
github-token: ${{secrets.GITHUB_TOKEN}}
122+
script: |
123+
github.rest.issues.createComment({
124+
issue_number: context.issue.number,
125+
owner: context.repo.owner,
126+
repo: context.repo.repo,
127+
body: `✅ Performance tests complete! Result summary:
128+
- Total requests: **${{ needs.run-perftests.outputs.request_count }}**
129+
- Total failures: **${{ needs.run-perftests.outputs.failure_count }}**
130+
- Min response time: **${{ needs.run-perftests.outputs.min_time }} ms**
131+
- Max response time: **${{ needs.run-perftests.outputs.max_time }} ms**
132+
- Average response time: **${{ needs.run-perftests.outputs.avg_time }} ms**
133+
- Median response time: **${{ needs.run-perftests.outputs.med_time }} ms**
134+
- Requests per second: **${{ needs.run-perftests.outputs.requests_per_sec }}**
135+
136+
Click here to view full results: ${{ env.GITHUB_WORKFLOW_URL }}.`
137+
})
138+
139+
comment-failure:
140+
runs-on: ubuntu-latest
141+
if: failure()
142+
needs: run-perftests
143+
steps:
144+
- name: Comment run results
145+
env:
146+
GITHUB_WORKFLOW_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
147+
uses: actions/github-script@v5
148+
with:
149+
github-token: ${{secrets.GITHUB_TOKEN}}
150+
script: |
151+
github.rest.issues.createComment({
152+
issue_number: context.issue.number,
153+
owner: context.repo.owner,
154+
repo: context.repo.repo,
155+
body: `❌ Performance tests failed! Click here to view full results: ${{ env.GITHUB_WORKFLOW_URL }}.`
156+
})

deploy.json

+16-15
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@
2525
"match": "^.*\\.(py)$",
2626
"add-header-comment": true
2727
},
28+
{
29+
"type": "move",
30+
"src": "src/server/utils",
31+
"dst": "[[package]]/server/utils/",
32+
"match": "^.*\\.(py)$",
33+
"add-header-comment": true
34+
},
2835
{
2936
"type": "move",
3037
"src": "src/server/endpoints",
@@ -40,6 +47,15 @@
4047
"add-header-comment": true
4148
},
4249

50+
"// acquisition - common",
51+
{
52+
"type": "move",
53+
"src": "src/acquisition/common/",
54+
"dst": "[[package]]/acquisition/common/",
55+
"match": "^.*\\.(py)$",
56+
"add-header-comment": true
57+
},
58+
4359
"// acquisition - fluview",
4460
{
4561
"type": "move",
@@ -65,11 +81,6 @@
6581
"dst": "[[package]]/acquisition/cdcp/",
6682
"match": "^.*\\.(py)$",
6783
"add-header-comment": true
68-
},{
69-
"type": "move",
70-
"src": "src/acquisition/cdcp/cdc_upload.php",
71-
"dst": "[[auto_web]]/cdc_upload/index.php",
72-
"add-header-comment": true
7384
},
7485

7586
"// acquisition - ght",
@@ -107,16 +118,6 @@
107118
"dst": "[[package]]/acquisition/wiki/",
108119
"match": "^.*\\.(py)$",
109120
"add-header-comment": true
110-
},{
111-
"type": "move",
112-
"src": "src/acquisition/wiki/master.php",
113-
"dst": "[[auto_web]]/wiki/master.php",
114-
"add-header-comment": true
115-
},{
116-
"type": "move",
117-
"src": "src/acquisition/wiki/dashboard.php",
118-
"dst": "[[auto_web]]/wiki/index.php",
119-
"add-header-comment": true
120121
},
121122

122123
"// acquisition - flusurv",

dev/docker/web/epidata/Dockerfile

-11
This file was deleted.

dev/docker/web/epidata/README.md

-22
This file was deleted.

dev/docker/web/epidata/assets/database_config.php

-7
This file was deleted.

dev/local/Makefile

+14-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ LOG_DB:=delphi_database_epidata_$(NOW).log
6767
WEB_CONTAINER_ID:=$(shell docker ps -q --filter 'name=delphi_web_epidata')
6868
DATABASE_CONTAINER_ID:=$(shell docker ps -q --filter 'name=delphi_database_epidata')
6969

70+
M1=
71+
ifeq ($(shell uname -smp), Darwin arm64 arm)
72+
$(info M1 system detected, changing docker platform to linux/amd64.)
73+
override M1 =--platform linux/amd64
74+
endif
7075

7176
.PHONY=web
7277
web:
@@ -80,11 +85,14 @@ web:
8085

8186
@# Build the web_epidata image
8287
@cd repos/delphi/delphi-epidata;\
83-
docker build -t delphi_web_epidata -f ./devops/Dockerfile .;\
88+
docker build -t delphi_web_epidata\
89+
$(M1) \
90+
-f ./devops/Dockerfile .;\
8491
cd -
8592

8693
@# Run the web server
8794
@docker run --rm -p 127.0.0.1:10080:80 \
95+
$(M1) \
8896
--env "SQLALCHEMY_DATABASE_URI=$(sqlalchemy_uri)" \
8997
--env "FLASK_SECRET=abc" --env "FLASK_PREFIX=/epidata" --env "LOG_DEBUG" \
9098
--network delphi-net --name delphi_web_epidata \
@@ -102,10 +110,12 @@ db:
102110

103111
@# Build the database_epidata image
104112
@docker build -t delphi_database_epidata \
113+
$(M1) \
105114
-f repos/delphi/delphi-epidata/dev/docker/database/epidata/Dockerfile .
106115

107116
@# Run the database
108117
@docker run --rm -p 127.0.0.1:13306:3306 \
118+
$(M1) \
109119
--network delphi-net --name delphi_database_epidata \
110120
--cap-add=sys_nice \
111121
delphi_database_epidata >$(LOG_DB) 2>&1 &
@@ -120,6 +130,7 @@ db:
120130
.PHONY=py
121131
py:
122132
@docker build -t delphi_web_python \
133+
$(M1) \
123134
-f repos/delphi/delphi-epidata/dev/docker/python/Dockerfile .
124135

125136
.PHONY=all
@@ -128,6 +139,7 @@ all: db web py
128139
.PHONY=test
129140
test:
130141
@docker run -i --rm --network delphi-net \
142+
$(M1) \
131143
--mount type=bind,source=$(CWD)repos/delphi/delphi-epidata,target=/usr/src/app/repos/delphi/delphi-epidata,readonly \
132144
--mount type=bind,source=$(CWD)repos/delphi/delphi-epidata/src,target=/usr/src/app/delphi/epidata,readonly \
133145
--env "SQLALCHEMY_DATABASE_URI=$(sqlalchemy_uri)" \
@@ -137,6 +149,7 @@ test:
137149
.PHONY=bash
138150
bash:
139151
@docker run -it --rm --network delphi-net \
152+
$(M1) \
140153
--mount type=bind,source=$(CWD)repos/delphi/delphi-epidata,target=/usr/src/app/repos/delphi/delphi-epidata,readonly \
141154
--mount type=bind,source=$(CWD)repos/delphi/delphi-epidata/src,target=/usr/src/app/delphi/epidata,readonly \
142155
--env "SQLALCHEMY_DATABASE_URI=$(sqlalchemy_uri)" \

dev/local/setup.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = Delphi Development
3-
version = 0.4.6
3+
version = 0.4.7
44

55
[options]
66
packages =

docs/epidata_development.md

+3-39
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ above. The base images are built first, followed by the derived
116116
`epidata`-specific images.
117117

118118
- The [`delphi_web_epidata` image](https://github.com/cmu-delphi/delphi-epidata/blob/main/dev/docker/web/epidata/README.md) adds
119-
the Epidata API to the `delphi_web` image.
119+
the Epidata API to the `delphi_web_epidata` image.
120120
- The
121121
[`delphi_database_epidata` image](https://github.com/cmu-delphi/delphi-epidata/blob/main/dev/docker/database/epidata/README.md)
122122
adds user accounts, `epidata` & other appropriate databases, and relevant tables
@@ -125,14 +125,8 @@ above. The base images are built first, followed by the derived
125125
From the root of your workspace, all of the images can be built as follows:
126126

127127
```bash
128-
docker build -t delphi_web \
129-
-f repos/delphi/operations/dev/docker/web/Dockerfile .
130-
131-
docker build -t delphi_web_epidata \
132-
-f repos/delphi/delphi-epidata/dev/docker/web/epidata/Dockerfile .
133-
134-
docker build -t delphi_database \
135-
-f repos/delphi/operations/dev/docker/database/Dockerfile .
128+
docker build -t delphi_web_epidata\
129+
-f ./devops/Dockerfile .;\
136130

137131
docker build -t delphi_database_epidata \
138132
-f repos/delphi/delphi-epidata/dev/docker/database/epidata/Dockerfile .
@@ -394,33 +388,3 @@ The command above maps two local directories into the container:
394388
- `/repos/delphi/delphi-epidata/src`: Just the source code, which forms the
395389
container's `delphi.epidata` python package.
396390

397-
### server code
398-
399-
Local web sources (e.g. PHP files) can be bind-mounted into a
400-
`delphi_web_epidata` container as follows:
401-
402-
```bash
403-
docker run --rm -p 127.0.0.1:10080:80 \
404-
--mount type=bind,source="$(pwd)"/repos/delphi/delphi-epidata/src/server/api.php,target=/var/www/html/epidata/api.php,readonly \
405-
--mount type=bind,source="$(pwd)"/repos/delphi/delphi-epidata/src/server/api_helpers.php,target=/var/www/html/epidata/api_helpers.php,readonly \
406-
--network delphi-net --name delphi_web_epidata \
407-
delphi_web_epidata
408-
```
409-
410-
The command above mounts two specific files into the image. It may be tempting
411-
to bind mount the `src/server` directory rather than specific files, however
412-
that is currently problematic for a couple of reasons:
413-
414-
1. `server/.htaccess` [from the local repository](https://github.com/cmu-delphi/delphi-epidata/blob/main/src/server/.htaccess) uses
415-
the `Header` directive. However, the webserver in the container doesn't have
416-
the corresponding module enabled. This causes the server to deny access to
417-
the API.
418-
2. `server/database_config.php`
419-
[in the image](https://github.com/cmu-delphi/delphi-epidata/blob/main/dev/docker/web/epidata/assets/database_config.php) contains
420-
database credentials for use in conjunction with the
421-
`delphi_database_epidata` container during development. However, the same
422-
file from [the local repository](https://github.com/cmu-delphi/delphi-epidata/blob/main/src/server/database_config.php) only
423-
contains placeholder values. This prevents communication with the database.
424-
425-
There is currently no benefit to bind-mounting sources into the database
426-
container because schema changes require restarting the container anyway.

0 commit comments

Comments
 (0)