-
Notifications
You must be signed in to change notification settings - Fork 4
283 lines (278 loc) · 11.6 KB
/
Copy pathtest.yml
File metadata and controls
283 lines (278 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
on:
workflow_dispatch:
pull_request:
branches:
- develop
paths-ignore:
- '**.md'
- 'docs/**'
name: test
jobs:
tests:
if: ${{ github.event.action != 'closed' || github.event.pull_request.merged == true }}
runs-on: ubuntu-22.04
strategy:
# Surface every broken matrix entry in one run instead of
# cancelling the rest on the first failure.
fail-fast: false
matrix:
use-numpy:
- 0
- 1
python-version:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
- "pypy-3.9"
- "pypy-3.10"
proton-version:
- "latest"
name: ${{ matrix.python-version }} PROTON=${{ matrix.proton-version }} NUMPY=${{ matrix.use-numpy }}
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
architecture: x64
env:
if: ${{ matrix.python-version == 3.5 }}
PIP_TRUSTED_HOST: "pypi.python.org pypi.org files.pythonhosted.org"
# - name: Login to Docker Hub
# uses: docker/login-action@v1
# with:
# username: ${{ secrets.DOCKER_HUB_USERNAME }}
# password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Install flake8
run: |
pip install --upgrade pip setuptools wheel
pip install flake8 flake8-print
- name: Run flake8
run: flake8
- name: Start Proton server and client containers
run: |
echo "VERSION=${{ matrix.proton-version }}" > tests/.env
echo "ORG=timeplus" >> tests/.env
docker compose -f tests/docker-compose.yml up -d
- name: Setup proton-client proxy for docker
run: |
# Faking proton-client real communication with container via docker exec.
echo -e '#!/bin/bash\n\ndocker exec -e "`env | grep ^TZ=`" test-proton-client timeplusd client "$@"' | sudo tee /usr/local/bin/proton-client > /dev/null
sudo chmod +x /usr/local/bin/proton-client
# Overriding setup.cfg. Set host=proton-server
sed -i 's/^host=localhost$/host=proton-server/' setup.cfg
# Make host think that proton-server is localhost
echo '127.0.0.1 proton-server' | sudo tee /etc/hosts > /dev/null
- name: Wait for Proton server
run: |
# --host proton-server: the proton-client proxy docker-execs
# into the client container, where localhost is NOT the server.
probe() { proton-client --host proton-server --port 8463 --query "SELECT 1"; }
for i in $(seq 1 150); do
if probe >/dev/null 2>&1; then
echo "server is up (attempt $i)"; exit 0
fi
if [ $((i % 15)) -eq 0 ]; then
echo "still waiting (attempt $i); container: $(docker ps -a --filter name=test-proton-server --format '{{.Status}}')"
fi
sleep 2
done
echo "server failed to come up"
echo "--- container status:"
docker ps -a --filter name=test-proton
echo "--- docker logs (tail):"
docker logs test-proton-server 2>&1 | tail -50
echo "--- server error log (tail):"
docker exec test-proton-server tail -100 /var/log/timeplusd-server/timeplusd-server.err.log || true
echo "--- last client error:"
probe || true
exit 1
env:
TZ: UTC
- name: Build cython extensions with tracing
run: CYTHON_TRACE=1 python setup.py build_ext --define CYTHON_TRACE
if: ${{ !contains(matrix.python-version, 'pypy') }}
- name: Install requirements
run: |
# Modern coveralls works with GitHub Actions and pulls a
# coverage release that ships C-tracer wheels — the Cython
# coverage plugin needs that tracer.
pip install coveralls
pip install cython
python testsrequire.py
# pip resolves Requires-Python metadata; the legacy
# `setup.py develop` easy_install path ignored it and pulled
# tzlocal 5.x (zoneinfo) onto Python 3.8.
pip install -e . --no-build-isolation
# Limit each test time execution.
pip install pytest-timeout
env:
USE_NUMPY: ${{ matrix.use-numpy }}
- name: Run tests
# coverage's C tracer doesn't exist on pypy and the Cython
# coverage plugin refuses to load without it — run plain pytest
# there (no compiled extensions to trace on pypy anyway).
run: |
if [[ "${{ matrix.python-version }}" == pypy* ]]; then
python -m pytest --timeout=10 -v
else
coverage run -m pytest --timeout=10 -v
fi
timeout-minutes: 5
env:
# Set initial TZ for docker exec -e "`env | grep ^TZ`"
TZ: UTC
- name: Upload coverage
run: coveralls
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_PARALLEL: true
COVERALLS_FLAG_NAME: ${{ matrix.python-version }} CH=${{ matrix.proton-version }} NUMPY=${{ matrix.use-numpy }}
# Free-threaded 3.14 (cp314t) smoke. Locks in that (a) the wheel builds on
# 3.14t, (b) every compiled extension imports with the stdlib compression
# modules (zlib / bz2 / compression.zstd / lzma) artificially blocked —
# the invariant CYTHON_COMPRESS_STRINGS=0 in setup.py guarantees — and
# (c) the GIL stays disabled after import: all four extensions declare
# freethreading_compatible, so a single regression here re-enables the
# GIL and fails the assert inside tests/smoke_no_compression.py.
smoke-ft:
name: 3.14t FT build + import smoke
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Set up free-threaded Python 3.14
uses: actions/setup-python@v5
with:
python-version: "3.14t"
- name: Install driver (pulls pytz/tzlocal and compiles extensions under 3.14t)
run: |
python -m pip install --upgrade pip
python -m pip install cython setuptools wheel
# Install into site-packages so the smoke script resolves proton_driver
# unambiguously regardless of cwd. A plain `build_ext --inplace` would
# leave the driver package importable only when cwd==project root.
python -m pip install .
- name: Report FT runtime state
run: |
python -c "import sys; print('python', sys.version); print('GIL enabled at startup:', getattr(sys, '_is_gil_enabled', lambda: True)())"
- name: Block-import smoke (zlib / bz2 / compression.zstd / lzma)
run: python tests/smoke_no_compression.py
- name: Threaded extension stress (GIL must stay off)
# pytest puts the repo checkout first on sys.path (tests/ is a
# package), shadowing the pip-installed driver — so the source
# tree needs its own compiled extensions.
run: |
python setup.py build_ext --inplace
python -m pip install pytest
python -m pytest tests/test_freethreading.py::ExtensionConcurrencyTestCase -v
# The release workflow is the only other place cibuildwheel runs, so its
# config rots invisibly: the stale musllinux_1_1 image pin killed release
# run 27423060149 at startup despite fully green PR checks. cibuildwheel
# resolves every image option upfront (verified: a bad musllinux pin fails
# this job in seconds even though it builds a manylinux target), so
# building one real wheel here surfaces config breakage — and runs the
# in-container block-import smoke test — on every PR instead of at
# release time.
cibuildwheel-smoke:
name: cibuildwheel config + single-wheel build
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Build one wheel through cibuildwheel
# Keep the version in lockstep with the release workflow
# (.github/workflows/actions.yml) — validating with a different
# cibuildwheel than the release uses defeats the purpose.
uses: pypa/cibuildwheel@v3.4.1
with:
only: cp314t-manylinux_x86_64
coveralls-finished:
name: Indicate completion to coveralls.io
needs: tests
continue-on-error: true
runs-on: ubuntu-latest
steps:
- name: Finished
uses: coverallsapp/github-action@v2.3.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel-finished: true
valgrind:
name: Valgrind check
needs: tests
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.8
architecture: x64
- name: Install valgrind
run: sudo apt-get update && sudo apt-get install -y valgrind
# - name: Login to Docker Hub
# uses: docker/login-action@v1
# with:
# username: ${{ secrets.DOCKER_HUB_USERNAME }}
# password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Start Proton server and client containers
run: |
echo "VERSION=$VERSION" > tests/.env
echo "ORG=timeplus" >> tests/.env
docker compose -f tests/docker-compose.yml up -d
env:
VERSION: latest
- name: Setup proton-client proxy for docker
run: |
# Faking proton-client real communication with container via docker exec.
echo -e '#!/bin/bash\n\ndocker exec -e "`env | grep ^TZ=`" test-proton-client timeplusd client "$@"' | sudo tee /usr/local/bin/proton-client > /dev/null
sudo chmod +x /usr/local/bin/proton-client
# Overriding setup.cfg. Set host=proton-server
sed -i 's/^host=localhost$/host=proton-server/' setup.cfg
# Make host think that proton-server is localhost
echo '127.0.0.1 proton-server' | sudo tee /etc/hosts > /dev/null
- name: Wait for Proton server
run: |
# --host proton-server: the proton-client proxy docker-execs
# into the client container, where localhost is NOT the server.
probe() { proton-client --host proton-server --port 8463 --query "SELECT 1"; }
for i in $(seq 1 150); do
if probe >/dev/null 2>&1; then
echo "server is up (attempt $i)"; exit 0
fi
if [ $((i % 15)) -eq 0 ]; then
echo "still waiting (attempt $i); container: $(docker ps -a --filter name=test-proton-server --format '{{.Status}}')"
fi
sleep 2
done
echo "server failed to come up"
echo "--- container status:"
docker ps -a --filter name=test-proton
echo "--- docker logs (tail):"
docker logs test-proton-server 2>&1 | tail -50
echo "--- server error log (tail):"
docker exec test-proton-server tail -100 /var/log/timeplusd-server/timeplusd-server.err.log || true
echo "--- last client error:"
probe || true
exit 1
env:
TZ: UTC
- name: Install requirements
run: |
# --no-build-isolation needs setuptools/wheel preinstalled.
pip install --upgrade pip setuptools wheel
python testsrequire.py
pip install -e . --no-build-isolation
env:
USE_NUMPY: 1
- name: Run tests under valgrind
run: valgrind --error-exitcode=1 --suppressions=valgrind.supp pytest -v
env:
# Set initial TZ for docker exec -e "`env | grep ^TZ`"
TZ: UTC
USE_NUMPY: 1
PYTHONMALLOC: malloc