CI(build-and-test): run regression tests on arm (#8552)

## Problem

We want to run our regression test suite on ARM.

## Summary of changes
- run regression tests on release ARM builds
- run `build-neon` (including rust tests) on debug ARM builds
- add `arch` parameter to test to distinguish them in the allure report
and in a database
This commit is contained in:
Alexander Bayandin
2024-08-21 14:29:11 +01:00
committed by GitHub
parent 3b8016488e
commit 75175f3628
5 changed files with 47 additions and 9 deletions

View File

@@ -169,10 +169,8 @@ runs:
EXTRA_PARAMS="--durations-path $TEST_OUTPUT/benchmark_durations.json $EXTRA_PARAMS" EXTRA_PARAMS="--durations-path $TEST_OUTPUT/benchmark_durations.json $EXTRA_PARAMS"
fi fi
if [[ "${{ inputs.build_type }}" == "debug" ]]; then if [[ $BUILD_TYPE == "debug" && $RUNNER_ARCH == 'X64' ]]; then
cov_prefix=(scripts/coverage "--profraw-prefix=$GITHUB_JOB" --dir=/tmp/coverage run) cov_prefix=(scripts/coverage "--profraw-prefix=$GITHUB_JOB" --dir=/tmp/coverage run)
elif [[ "${{ inputs.build_type }}" == "release" ]]; then
cov_prefix=()
else else
cov_prefix=() cov_prefix=()
fi fi

View File

@@ -94,11 +94,16 @@ jobs:
# We run tests with addtional features, that are turned off by default (e.g. in release builds), see # We run tests with addtional features, that are turned off by default (e.g. in release builds), see
# corresponding Cargo.toml files for their descriptions. # corresponding Cargo.toml files for their descriptions.
- name: Set env variables - name: Set env variables
env:
ARCH: ${{ inputs.arch }}
run: | run: |
CARGO_FEATURES="--features testing" CARGO_FEATURES="--features testing"
if [[ $BUILD_TYPE == "debug" ]]; then if [[ $BUILD_TYPE == "debug" && $ARCH == 'x64' ]]; then
cov_prefix="scripts/coverage --profraw-prefix=$GITHUB_JOB --dir=/tmp/coverage run" cov_prefix="scripts/coverage --profraw-prefix=$GITHUB_JOB --dir=/tmp/coverage run"
CARGO_FLAGS="--locked" CARGO_FLAGS="--locked"
elif [[ $BUILD_TYPE == "debug" ]]; then
cov_prefix=""
CARGO_FLAGS="--locked"
elif [[ $BUILD_TYPE == "release" ]]; then elif [[ $BUILD_TYPE == "release" ]]; then
cov_prefix="" cov_prefix=""
CARGO_FLAGS="--locked --release" CARGO_FLAGS="--locked --release"
@@ -158,6 +163,8 @@ jobs:
# Do install *before* running rust tests because they might recompile the # Do install *before* running rust tests because they might recompile the
# binaries with different features/flags. # binaries with different features/flags.
- name: Install rust binaries - name: Install rust binaries
env:
ARCH: ${{ inputs.arch }}
run: | run: |
# Install target binaries # Install target binaries
mkdir -p /tmp/neon/bin/ mkdir -p /tmp/neon/bin/
@@ -172,7 +179,7 @@ jobs:
done done
# Install test executables and write list of all binaries (for code coverage) # Install test executables and write list of all binaries (for code coverage)
if [[ $BUILD_TYPE == "debug" ]]; then if [[ $BUILD_TYPE == "debug" && $ARCH == 'x64' ]]; then
# Keep bloated coverage data files away from the rest of the artifact # Keep bloated coverage data files away from the rest of the artifact
mkdir -p /tmp/coverage/ mkdir -p /tmp/coverage/
@@ -243,8 +250,8 @@ jobs:
uses: ./.github/actions/save-coverage-data uses: ./.github/actions/save-coverage-data
regress-tests: regress-tests:
# Run test on x64 only # Don't run regression tests on debug arm64 builds
if: inputs.arch == 'x64' if: inputs.build-type != 'debug' || inputs.arch != 'arm64'
needs: [ build-neon ] needs: [ build-neon ]
runs-on: ${{ fromJson(format('["self-hosted", "{0}"]', inputs.arch == 'arm64' && 'large-arm64' || 'large')) }} runs-on: ${{ fromJson(format('["self-hosted", "{0}"]', inputs.arch == 'arm64' && 'large-arm64' || 'large')) }}
container: container:

View File

@@ -198,7 +198,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
arch: [ x64 ] arch: [ x64, arm64 ]
# Do not build or run tests in debug for release branches # Do not build or run tests in debug for release branches
build-type: ${{ fromJson((startsWith(github.ref_name, 'release') && github.event_name == 'push') && '["release"]' || '["debug", "release"]') }} build-type: ${{ fromJson((startsWith(github.ref_name, 'release') && github.event_name == 'push') && '["release"]' || '["debug", "release"]') }}
include: include:

View File

@@ -18,6 +18,7 @@ import psycopg2
from psycopg2.extras import execute_values from psycopg2.extras import execute_values
CREATE_TABLE = """ CREATE_TABLE = """
CREATE TYPE arch AS ENUM ('ARM64', 'X64', 'UNKNOWN');
CREATE TABLE IF NOT EXISTS results ( CREATE TABLE IF NOT EXISTS results (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
parent_suite TEXT NOT NULL, parent_suite TEXT NOT NULL,
@@ -28,6 +29,7 @@ CREATE TABLE IF NOT EXISTS results (
stopped_at TIMESTAMPTZ NOT NULL, stopped_at TIMESTAMPTZ NOT NULL,
duration INT NOT NULL, duration INT NOT NULL,
flaky BOOLEAN NOT NULL, flaky BOOLEAN NOT NULL,
arch arch DEFAULT 'X64',
build_type TEXT NOT NULL, build_type TEXT NOT NULL,
pg_version INT NOT NULL, pg_version INT NOT NULL,
run_id BIGINT NOT NULL, run_id BIGINT NOT NULL,
@@ -35,7 +37,7 @@ CREATE TABLE IF NOT EXISTS results (
reference TEXT NOT NULL, reference TEXT NOT NULL,
revision CHAR(40) NOT NULL, revision CHAR(40) NOT NULL,
raw JSONB COMPRESSION lz4 NOT NULL, raw JSONB COMPRESSION lz4 NOT NULL,
UNIQUE (parent_suite, suite, name, build_type, pg_version, started_at, stopped_at, run_id) UNIQUE (parent_suite, suite, name, arch, build_type, pg_version, started_at, stopped_at, run_id)
); );
""" """
@@ -50,6 +52,7 @@ class Row:
stopped_at: datetime stopped_at: datetime
duration: int duration: int
flaky: bool flaky: bool
arch: str
build_type: str build_type: str
pg_version: int pg_version: int
run_id: int run_id: int
@@ -121,6 +124,14 @@ def ingest_test_result(
raw.pop("labels") raw.pop("labels")
raw.pop("extra") raw.pop("extra")
# All allure parameters are prefixed with "__", see test_runner/fixtures/parametrize.py
parameters = {
p["name"].removeprefix("__"): p["value"]
for p in test["parameters"]
if p["name"].startswith("__")
}
arch = parameters.get("arch", "UNKNOWN").strip("'")
build_type, pg_version, unparametrized_name = parse_test_name(test["name"]) build_type, pg_version, unparametrized_name = parse_test_name(test["name"])
labels = {label["name"]: label["value"] for label in test["labels"]} labels = {label["name"]: label["value"] for label in test["labels"]}
row = Row( row = Row(
@@ -132,6 +143,7 @@ def ingest_test_result(
stopped_at=datetime.fromtimestamp(test["time"]["stop"] / 1000, tz=timezone.utc), stopped_at=datetime.fromtimestamp(test["time"]["stop"] / 1000, tz=timezone.utc),
duration=test["time"]["duration"], duration=test["time"]["duration"],
flaky=test["flaky"] or test["retriesStatusChange"], flaky=test["flaky"] or test["retriesStatusChange"],
arch=arch,
build_type=build_type, build_type=build_type,
pg_version=pg_version, pg_version=pg_version,
run_id=run_id, run_id=run_id,

View File

@@ -1,6 +1,7 @@
import os import os
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
import allure
import pytest import pytest
import toml import toml
from _pytest.python import Metafunc from _pytest.python import Metafunc
@@ -91,3 +92,23 @@ def pytest_generate_tests(metafunc: Metafunc):
and (platform := os.getenv("PLATFORM")) is not None and (platform := os.getenv("PLATFORM")) is not None
): ):
metafunc.parametrize("platform", [platform.lower()]) metafunc.parametrize("platform", [platform.lower()])
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(*args, **kwargs):
# Add test parameters to Allue report to distinguish the same tests with different parameters.
# Names has `__` prefix to avoid conflicts with `pytest.mark.parametrize` parameters
# A mapping between `uname -m` and `RUNNER_ARCH` values.
# `RUNNER_ARCH` environment variable is set on GitHub Runners,
# possible values are X86, X64, ARM, or ARM64.
# See https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables
uname_m = {
"aarch64": "ARM64",
"arm64": "ARM64",
"x86_64": "X64",
}.get(os.uname().machine, "UNKNOWN")
arch = os.getenv("RUNNER_ARCH", uname_m)
allure.dynamic.parameter("__arch", arch)
yield