@@ -3,9 +3,8 @@ name: backend
33on :
44 push :
55 branches :
6- - master
7- pull_request :
8- types : [opened, synchronize, reopened, labeled]
6+ - mchen/tiered-xdist-v2
7+ - mchen/tiered-xdist-v2-clean
98 workflow_dispatch :
109
1110# Cancel in progress workflows on pull_requests.
@@ -204,15 +203,24 @@ jobs:
204203 needs : [files-changed, prepare-selective-tests]
205204 name : calculate test shards
206205 runs-on : ubuntu-24.04
207- timeout-minutes : 5
206+ timeout-minutes : ${{ needs.prepare-selective-tests.outputs.has-selected-tests == 'true' && 5 || 1 }}
208207 outputs :
209- shard-count : ${{ steps.calculate-shards.outputs.shard-count }}
210- shard-indices : ${{ steps.calculate-shards.outputs.shard-indices }}
208+ shard-count : ${{ steps.static-shards.outputs.shard-count || steps. calculate-shards.outputs.shard-count }}
209+ shard-indices : ${{ steps.static-shards.outputs.shard-indices || steps. calculate-shards.outputs.shard-indices }}
211210
212211 steps :
212+ - name : Use default shards (no selective testing)
213+ id : static-shards
214+ if : needs.prepare-selective-tests.outputs.has-selected-tests != 'true'
215+ run : |
216+ echo "shard-count=22" >> "$GITHUB_OUTPUT"
217+ echo "shard-indices=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]" >> "$GITHUB_OUTPUT"
218+
213219 - uses : actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
220+ if : needs.prepare-selective-tests.outputs.has-selected-tests == 'true'
214221
215222 - name : Setup sentry env
223+ if : needs.prepare-selective-tests.outputs.has-selected-tests == 'true'
216224 uses : ./.github/actions/setup-sentry
217225 id : setup
218226 with :
@@ -228,8 +236,9 @@ jobs:
228236
229237 - name : Calculate test shards
230238 id : calculate-shards
239+ if : needs.prepare-selective-tests.outputs.has-selected-tests == 'true'
231240 env :
232- SELECTED_TESTS_FILE : ${{ needs.prepare-selective-tests.outputs.has-selected-tests == 'true' && ' .artifacts/selected-tests.txt' || '' }}
241+ SELECTED_TESTS_FILE : ' .artifacts/selected-tests.txt'
233242 SELECTED_TEST_COUNT : ${{ needs.prepare-selective-tests.outputs.test-count || '' }}
234243 run : |
235244 python3 .github/workflows/scripts/calculate-backend-test-shards.py
@@ -258,9 +267,11 @@ jobs:
258267 instance : ${{ fromJSON(needs.calculate-shards.outputs.shard-indices) }}
259268
260269 env :
261- # Dynamic total from calculate-shards
262270 MATRIX_INSTANCE_TOTAL : ${{ needs.calculate-shards.outputs.shard-count }}
263271 TEST_GROUP_STRATEGY : roundrobin
272+ PYTHONHASHSEED : ' 0'
273+ XDIST_PER_WORKER_SNUBA : ' 1'
274+ XDIST_WORKERS : ' 3'
264275
265276 steps :
266277 - uses : actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
@@ -278,6 +289,50 @@ jobs:
278289 sudo install -m 755 odiff-linux-x64 /usr/local/bin/odiff
279290 rm odiff-linux-x64
280291
292+ - name : Bootstrap per-worker Snuba instances
293+ if : env.XDIST_PER_WORKER_SNUBA == '1'
294+ run : |
295+ set -eo pipefail
296+ XDIST_N=${XDIST_WORKERS:-3}
297+ SNUBA_IMAGE=$(docker inspect snuba-snuba-1 --format '{{.Config.Image}}')
298+ SNUBA_NETWORK=$(docker inspect snuba-snuba-1 --format '{{range $k, $v := .NetworkSettings.Networks}}{{$k}}{{end}}')
299+ if [ -z "$SNUBA_IMAGE" ] || [ -z "$SNUBA_NETWORK" ]; then
300+ echo "ERROR: Could not inspect snuba-snuba-1 container. Is devservices running?"
301+ exit 1
302+ fi
303+
304+ for i in $(seq 0 $((XDIST_N - 1))); do
305+ (
306+ WORKER_DB="default_gw${i}"
307+ WORKER_PORT=$((1230 + i))
308+ curl -sf 'http://localhost:8123/' --data-binary "CREATE DATABASE IF NOT EXISTS ${WORKER_DB}"
309+ docker run --rm --network "$SNUBA_NETWORK" \
310+ -e "CLICKHOUSE_DATABASE=${WORKER_DB}" -e "CLICKHOUSE_HOST=clickhouse" \
311+ -e "CLICKHOUSE_PORT=9000" -e "CLICKHOUSE_HTTP_PORT=8123" \
312+ -e "DEFAULT_BROKERS=kafka:9093" -e "REDIS_HOST=redis" \
313+ -e "REDIS_PORT=6379" -e "REDIS_DB=1" -e "SNUBA_SETTINGS=docker" \
314+ "$SNUBA_IMAGE" bootstrap --force 2>&1 | tail -3
315+ docker run -d --name "snuba-gw${i}" --network "$SNUBA_NETWORK" \
316+ -p "${WORKER_PORT}:1218" \
317+ -e "CLICKHOUSE_DATABASE=${WORKER_DB}" -e "CLICKHOUSE_HOST=clickhouse" \
318+ -e "CLICKHOUSE_PORT=9000" -e "CLICKHOUSE_HTTP_PORT=8123" \
319+ -e "DEFAULT_BROKERS=kafka:9093" -e "REDIS_HOST=redis" \
320+ -e "REDIS_PORT=6379" -e "REDIS_DB=1" -e "SNUBA_SETTINGS=docker" \
321+ -e "DEBUG=1" "$SNUBA_IMAGE" api
322+ ) &
323+ done
324+ wait
325+
326+ for i in $(seq 0 $((XDIST_N - 1))); do
327+ WORKER_PORT=$((1230 + i))
328+ for attempt in $(seq 1 30); do
329+ if curl -sf "http://localhost:${WORKER_PORT}/health" > /dev/null 2>&1; then
330+ echo "[snuba-gw${i}] ready on port ${WORKER_PORT}"; break; fi
331+ [ "$attempt" -eq 30 ] && echo "[snuba-gw${i}] FAILED" && docker logs "snuba-gw${i}" 2>&1 | tail -20 && exit 1
332+ sleep 1
333+ done
334+ done
335+
281336 - name : Download selected tests artifact
282337 if : needs.prepare-selective-tests.outputs.has-selected-tests == 'true'
283338 uses : actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
@@ -289,7 +344,19 @@ jobs:
289344 env :
290345 SELECTED_TESTS_FILE : ${{ needs.prepare-selective-tests.outputs.has-selected-tests == 'true' && '.artifacts/selected-tests.txt' || '' }}
291346 run : |
292- make test-python-ci
347+ python3 -b -m pytest tests \
348+ --reuse-db \
349+ -n ${XDIST_WORKERS:-3} \
350+ --dist=loadfile \
351+ --ignore tests/acceptance \
352+ --ignore tests/apidocs \
353+ --ignore tests/js \
354+ --ignore tests/tools \
355+ --json-report \
356+ --json-report-file=".artifacts/pytest.json" \
357+ --json-report-omit=log \
358+ --junit-xml=.artifacts/pytest.junit.xml \
359+ -o junit_suite_name=pytest
293360
294361 - name : Report failures
295362 if : ${{ !cancelled() && github.event_name == 'pull_request' }}
@@ -306,6 +373,9 @@ jobs:
306373 - name : Inspect failure
307374 if : failure()
308375 run : |
376+ for name in $(docker ps -a --filter "name=snuba-gw" --format '{{.Names}}'); do
377+ echo "--- $name ---"; docker logs "$name" 2>&1 | tail -30
378+ done
309379 if command -v devservices; then
310380 devservices logs
311381 fi
0 commit comments