Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e1289db
CI2M: lint and build-check are deleted, test std2-all/py3.12/pg17 onl…
dmitry-lipetsk Jul 12, 2026
0876b5b
CI2M: Dockerfile--std2-all.tmpl is refactored
dmitry-lipetsk Jul 12, 2026
6ce2e1c
CI2M: Dockerfile--std2-all.tmpl is minimized (test app only)
dmitry-lipetsk Jul 12, 2026
59bf867
CI2M: Dockerfile--std2-all.tmpl does not correct /home/test/testgres/…
dmitry-lipetsk Jul 12, 2026
e6444bd
CI2M: cy.yml creates two machines, tests/helpers/global_data.py is up…
dmitry-lipetsk Jul 12, 2026
f27e094
CI2M: Dockerfile--std2-all.tmpl runs prove of 2m tests, too
dmitry-lipetsk Jul 12, 2026
2fd15b1
CI2M: All "std2-all" are tested (in minimal form)
dmitry-lipetsk Jul 12, 2026
a8b021f
CI2M: Try to use std2-all for all the PG versions (unification)
dmitry-lipetsk Jul 12, 2026
5480477
CI2M: std amd std-all are deleted (replaced with std2-all)
dmitry-lipetsk Jul 12, 2026
4a869af
CI2M: Dockerfile--ubuntu_24_04.tmpl is updated
dmitry-lipetsk Jul 12, 2026
b98920b
CI2M: Dockerfile--astralinux_1_7.tmpl is updated
dmitry-lipetsk Jul 12, 2026
58fd495
CI2M: altlinux-10/11 are updated
dmitry-lipetsk Jul 12, 2026
2d715ff
CI2M: all the stages and platforms are restored
dmitry-lipetsk Jul 12, 2026
a941463
CI2M: std2-all -> alpine
dmitry-lipetsk Jul 12, 2026
001cbd1
CI2M: case_suffix is added (to human names in CI console)
dmitry-lipetsk Jul 12, 2026
7f0248f
CI2M: all the tests are restored
dmitry-lipetsk Jul 12, 2026
577f9ba
fix: Detect and process zombie state of postmaster
dmitry-lipetsk Jul 12, 2026
f920a25
CI2M: (fix ubuntu) user 'test' is added into 'postgres' group
dmitry-lipetsk Jul 12, 2026
d77a34f
CI2M: all the tests are restored
dmitry-lipetsk Jul 12, 2026
e5f2347
get_pg_node_state is updated (T_PLATFORM_UTILS)
dmitry-lipetsk Jul 12, 2026
3f0349e
impl__test_pg_ctl_wait_option is updated to process zombies
dmitry-lipetsk Jul 12, 2026
37de589
CI2M: (alpine) SSH limits are increased
dmitry-lipetsk Jul 12, 2026
1f10354
CI2M: TestTestgresRemote::test_init__unk_LANG_and_LC_CTYPE is skipped…
dmitry-lipetsk Jul 12, 2026
cfd313d
CI2M: (fix) altlinux-11 runs all the tests
dmitry-lipetsk Jul 12, 2026
87a4022
test_set_env__thread_safety is corrected (slow work)
dmitry-lipetsk Jul 12, 2026
01efb4e
test_set_env__thread_safety is updated
dmitry-lipetsk Jul 12, 2026
b74e1cb
CI2M: ssh limits are inreased (alt, astra, ubuntu)
dmitry-lipetsk Jul 12, 2026
1248faa
CI2M: limits via docker run command
dmitry-lipetsk Jul 12, 2026
2447df1
CI2M: print nproc
dmitry-lipetsk Jul 12, 2026
b288657
Merge branch 'master' into D20260712_001--ci-creates-two-machines
dmitry-lipetsk Jul 12, 2026
f7bfbf6
CI2M: run_tests prints storage state of local and remote machines
dmitry-lipetsk Jul 13, 2026
68c85b1
FindPosmaster (linux) is rewritten
dmitry-lipetsk Jul 13, 2026
e3b72a6
[#247] PortManager__Generic2
dmitry-lipetsk Jul 13, 2026
76cf645
test_kill_backgroud_writer__ok is improved (it fails under load)
dmitry-lipetsk Jul 13, 2026
75831d0
Merge branch 'master' into D20260712_001--ci-creates-two-machines
dmitry-lipetsk Jul 13, 2026
31f702d
bound_ports is deleted (it is critical change)
dmitry-lipetsk Jul 13, 2026
0df53ac
port_manager__generic2 is updated (noqa E721 is deleted)
dmitry-lipetsk Jul 13, 2026
78dc38c
port_manager__generic2 is updated (ruff)
dmitry-lipetsk Jul 13, 2026
21a8097
test_status__force_clean_postmaster_pid is rewritten
dmitry-lipetsk Jul 13, 2026
a320042
CI2M: DOCKER_HIGHLOAD_FLAGS
dmitry-lipetsk Jul 13, 2026
c3ea664
CI2M: run_tests -> 4 workers
dmitry-lipetsk Jul 13, 2026
2685b01
CI2M: Run containers with "--init" option
dmitry-lipetsk Jul 13, 2026
3b4a27f
test_testgres_common.py is updated
dmitry-lipetsk Jul 13, 2026
b0f1644
Merge branch 'master' into D20260712_001--ci-creates-two-machines
dmitry-lipetsk Jul 13, 2026
ca81132
Merge branch 'master' into D20260712_001--ci-creates-two-machines
dmitry-lipetsk Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 138 additions & 32 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,82 +74,115 @@ jobs:
fail-fast: false
matrix:
include:
- platform: "std2-all"
- platform: "alpine"
python: "3.7"
postgres: "17"
- platform: "std2-all"
case_suffix: "py3_07_xx-pg17_xx"
- platform: "alpine"
python: "3.8.0"
postgres: "17"
- platform: "std2-all"
case_suffix: "py3_08_88-pg17_xx"
- platform: "alpine"
python: "3.8"
postgres: "17"
- platform: "std2-all"
case_suffix: "py3_08_xx-pg17_xx"
- platform: "alpine"
python: "3.9"
postgres: "17"
- platform: "std2-all"
case_suffix: "py3_09_xx-pg17_xx"
- platform: "alpine"
python: "3.10"
postgres: "17"
- platform: "std2-all"
case_suffix: "py3_10_xx-pg17_xx"
- platform: "alpine"
python: "3.11"
postgres: "17"
- platform: "std2-all"
case_suffix: "py3_11_xx-pg17_xx"
- platform: "alpine"
python: "3.12"
postgres: "17"
- platform: "std2-all"
case_suffix: "py3_12_xx-pg17_xx"
- platform: "alpine"
python: "3.13"
postgres: "17"
- platform: "std2-all"
case_suffix: "py3_13_xx-pg17_xx"
- platform: "alpine"
python: "3.14"
postgres: "17"
- platform: "std"
python: "3"
case_suffix: "py3_14_xx-pg17_xx"
- platform: "alpine"
python: "3.12"
postgres: "10"
- platform: "std"
python: "3"
case_suffix: "py3_12_xx-pg10_xx"
- platform: "alpine"
python: "3.12"
postgres: "11"
- platform: "std"
python: "3"
case_suffix: "py3_12_xx-pg11_xx"
- platform: "alpine"
python: "3.12"
postgres: "12"
- platform: "std"
python: "3"
case_suffix: "py3_12_xx-pg12_xx"
- platform: "alpine"
python: "3.12"
postgres: "13"
- platform: "std"
python: "3"
case_suffix: "py3_12_xx-pg13_xx"
- platform: "alpine"
python: "3.12"
postgres: "14"
- platform: "std"
python: "3"
case_suffix: "py3_12_xx-pg14_xx"
- platform: "alpine"
python: "3.12"
postgres: "15"
- platform: "std"
python: "3"
case_suffix: "py3_12_xx-pg15_xx"
- platform: "alpine"
python: "3.12"
postgres: "16"
- platform: "std-all"
python: "3"
postgres: "17"
- platform: "std-all"
python: "3"
case_suffix: "py3_12_xx-pg16_xx"
- platform: "alpine"
python: "3.12"
postgres: "18"
case_suffix: "py3_12_xx-pg18_xx"
- platform: "ubuntu_24_04"
python: "3"
postgres: "17"
case_suffix: "py3_xx_xx-pg17_xx"
- platform: "altlinux_10"
python: "3"
postgres: "17"
case_suffix: "py3_xx_xx-pg17_xx"
- platform: "altlinux_11"
python: "3"
postgres: "17"
case_suffix: "py3_xx_xx-pg17_xx"
- platform: "astralinux_1_7"
python: "3"
postgres: "17"
case_suffix: "py3_xx_xx-pg17_xx"

name: "test: ${{ matrix.platform }} | ${{ matrix.case_suffix }}"

env:
BASE_SIGN: "${{ matrix.platform }}-py${{ matrix.python }}-pg${{ matrix.postgres }}"
BASE_SIGN: "${{ matrix.platform }}-${{ matrix.case_suffix }}"

DOCKER_HIGHLOAD_FLAGS: >-
--init
--sysctl net.core.somaxconn=4096
--sysctl net.ipv4.tcp_max_syn_backlog=4096
--ulimit nofile=524288:524288
--ulimit nproc=65535:65535
--sysctl net.ipv4.tcp_tw_reuse=1
--sysctl net.ipv4.ip_local_port_range="1024 65535"

steps:
- name: Prepare variables
run: |
echo "RUN_CFG__NOW=$(date +'%Y%m%d_%H%M%S')" >> $GITHUB_ENV
echo "RUN_CFG__LOGS_DIR=logs-${{ env.BASE_SIGN }}" >> $GITHUB_ENV
echo "RUN_CFG__DOCKER_IMAGE_NAME=tests-${{ env.BASE_SIGN }}" >> $GITHUB_ENV
echo "RUN_CFG__NETWORK_NAME=network-${{ env.BASE_SIGN }}" >> $GITHUB_ENV
echo "RUN_CFG__MACHINE1_NAME=machine1-${{ env.BASE_SIGN }}" >> $GITHUB_ENV
echo "RUN_CFG__MACHINE2_NAME=machine2-${{ env.BASE_SIGN }}" >> $GITHUB_ENV
echo "RUN_CFG__SSH_KEY_NAME=id_ed25519-${{ env.BASE_SIGN }}" >> $GITHUB_ENV
echo "---------- [$GITHUB_ENV]"
cat $GITHUB_ENV
- name: Checkout
Expand All @@ -158,10 +191,83 @@ jobs:
run: mkdir -p "${{ env.RUN_CFG__LOGS_DIR }}"
- name: Adjust logs folder permission
run: chmod -R 777 "${{ env.RUN_CFG__LOGS_DIR }}"
- name: Build local image ${{ matrix.alpine }}
- name: Build local image
run: docker build --build-arg PG_VERSION="${{ matrix.postgres }}" --build-arg PYTHON_VERSION="${{ matrix.python }}" -t "${{ env.RUN_CFG__DOCKER_IMAGE_NAME }}" -f Dockerfile--${{ matrix.platform }}.tmpl .
- name: Run
run: docker run $(bash <(curl -s https://codecov.io/env)) -t -v ${{ github.workspace }}/${{ env.RUN_CFG__LOGS_DIR }}:/home/test/testgres/logs "${{ env.RUN_CFG__DOCKER_IMAGE_NAME }}"
- name: Generate temporary SSH Key pair for CI
run: |
# Generate a key without a password directly on the GitHub Actions host
ssh-keygen -q -t ed25519 -N "" -f ${{ github.workspace }}/${{ env.RUN_CFG__SSH_KEY_NAME }}

- name: Setup network
run: |
docker network create ${{ env.RUN_CFG__NETWORK_NAME }}

- name: Run machine2 (for remote operations)
run: |
#
# "- sleep infinity" is a right command. Docker ignores "-" and runs "sleep infinity".
#
docker run -d -t \
${{ env.DOCKER_HIGHLOAD_FLAGS }} \
--sysctl net.ipv4.tcp_tw_reuse=1 \
--sysctl net.ipv4.ip_local_port_range="1024 65535" \
--network ${{ env.RUN_CFG__NETWORK_NAME }} \
--name ${{ env.RUN_CFG__MACHINE2_NAME }} \
"${{ env.RUN_CFG__DOCKER_IMAGE_NAME }}" \
sleep infinity

echo "Waiting for container ${{ env.RUN_CFG__MACHINE2_NAME }} to start ..."

# Set the timeout using the attempt counter
MAX_ATTEMPTS=50
ATTEMPT=0

until [ "$(docker container inspect --format '{{.State.Running}}' "${{ env.RUN_CFG__MACHINE2_NAME }}")" = "true" ]; do
ATTEMPT=$((ATTEMPT + 1))
if [ $ATTEMPT -ge $MAX_ATTEMPTS ]; then
echo "Error: Container did not start within the allotted time (timeout)!"
exit 1
fi
sleep 0.2
done

echo "Container successfully launched in $((ATTEMPT * 2 / 10)) second(s)!"

#
# Setup authorized_keys
#
cat ${{ github.workspace }}/${{ env.RUN_CFG__SSH_KEY_NAME }}.pub | \
docker exec -i -u test ${{ env.RUN_CFG__MACHINE2_NAME }} sh -c " \
cat >> /home/test/.ssh/authorized_keys && \
chmod 600 /home/test/.ssh/authorized_keys \
"

#
# Log status
#
docker exec -u root ${{ env.RUN_CFG__MACHINE2_NAME }} sh -c "
echo '--- INSIDE CONTAINER OS ---' && \
cat /etc/os-release && \
echo '--- INSIDE CONTAINER .SSH ---' && \
ls -la /home/test/.ssh/ \
"

- name: Run machine1 (main test container)
run: |
# Launch the main container, passing the private key to the .ssh folder of the test user.
# Pass environment variables so Python tests know where to start.
# Added the --rm flag so that the container is automatically deleted after the tests are completed
docker run --rm -t \
${{ env.DOCKER_HIGHLOAD_FLAGS }} \
--network ${{ env.RUN_CFG__NETWORK_NAME }} \
--name ${{ env.RUN_CFG__MACHINE1_NAME }} \
-v ${{ github.workspace }}/${{ env.RUN_CFG__LOGS_DIR }}:/home/test/testgres/logs \
-v ${{ github.workspace }}/${{ env.RUN_CFG__SSH_KEY_NAME }}:/home/test/testgres/id_ed25519_test:ro \
-e TEST_CFG__REMOTE_HOST="${{ env.RUN_CFG__MACHINE2_NAME }}" \
-e TEST_CFG__REMOTE_PORT="22" \
-e TEST_CFG__REMOTE_USERNAME="test" \
-e TEST_CFG__REMOTE_SSH_KEY="/home/test/testgres/id_ed25519_test" \
"${{ env.RUN_CFG__DOCKER_IMAGE_NAME }}"
- name: Upload Logs
uses: actions/upload-artifact@v7
if: always() # IT IS IMPORTANT!
Expand Down
148 changes: 148 additions & 0 deletions Dockerfile--alpine.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
ARG PG_VERSION=17
ARG PYTHON_VERSION=3.12

# --------------------------------------------- base1
FROM postgres:${PG_VERSION}-alpine AS base1

RUN apk add --no-cache \
coreutils \
bash \
mc \
procps \
openssh \
sshpass \
sudo \
git

RUN sed -i 's/#MaxStartups 10:30:100/MaxStartups 2000:30:2000/' /etc/ssh/sshd_config && \
sed -i 's/#MaxSessions 10/MaxSessions 500/' /etc/ssh/sshd_config && \
sed -i 's/#MaxAuthTries 6/MaxAuthTries 20/' /etc/ssh/sshd_config

# --------------------------------------------- base2_with_python-3
FROM base1 AS base2_with_python-3

RUN apk add --no-cache \
curl \
python3 \
python3-dev \
build-base \
musl-dev \
linux-headers \
# For pyenv \
patch \
xz-dev \
zip \
zlib-dev \
libffi-dev \
readline-dev \
openssl openssl-dev \
sqlite-dev \
bzip2-dev

ENV PYTHON_BINARY=python3

# --------------------------------------------- base3_with_python-3.7
FROM base2_with_python-3 AS base3_with_python-3.7
ENV PYTHON_VERSION=3.7

# --------------------------------------------- base3_with_python-3.8.0
FROM base2_with_python-3 AS base3_with_python-3.8.0
ENV PYTHON_VERSION=3.8.0

# --------------------------------------------- base3_with_python-3.8
FROM base2_with_python-3 AS base3_with_python-3.8
ENV PYTHON_VERSION=3.8

# --------------------------------------------- base3_with_python-3.9
FROM base2_with_python-3 AS base3_with_python-3.9
ENV PYTHON_VERSION=3.9

# --------------------------------------------- base3_with_python-3.10
FROM base2_with_python-3 AS base3_with_python-3.10
ENV PYTHON_VERSION=3.10

# --------------------------------------------- base3_with_python-3.11
FROM base2_with_python-3 AS base3_with_python-3.11
ENV PYTHON_VERSION=3.11

# --------------------------------------------- base3_with_python-3.12
FROM base2_with_python-3 AS base3_with_python-3.12
ENV PYTHON_VERSION=3.12

# --------------------------------------------- base3_with_python-3.13
FROM base2_with_python-3 AS base3_with_python-3.13
ENV PYTHON_VERSION=3.13

# --------------------------------------------- base3_with_python-3.14
FROM base2_with_python-3 AS base3_with_python-3.14
ENV PYTHON_VERSION=3.14

# --------------------------------------------- final
FROM base3_with_python-${PYTHON_VERSION} AS final

EXPOSE 22
RUN ssh-keygen -A

RUN adduser -D test && addgroup -S sudo && adduser test sudo

# It allows to use sudo without password
RUN echo "test ALL=(ALL:ALL) NOPASSWD:ALL" >> /etc/sudoers

# THIS CMD IS NEEDED TO CONNECT THROUGH SSH WITHOUT PASSWORD
RUN echo "test:*" | chpasswd -e

USER test
RUN curl https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
RUN ~/.pyenv/bin/pyenv install ${PYTHON_VERSION}
USER root

COPY --chown=test:test . /home/test/testgres
WORKDIR /home/test/testgres

ENV LANG=C.UTF-8

RUN chmod 700 /home/test/ && \
mkdir -p /home/test/.ssh && \
chown -R test:test /home/test/.ssh && \
mkdir /home/test/testgres/logs && \
chown -R test:test /home/test/testgres/logs

#
# \"$@\"
# - quote is important!
# - "DUMMY-DUMMY-DUMMY" will be ignored. Do not ask me "why?". AXEZ.
#
ENTRYPOINT ["sh", "-c", " \
set -eux; \
echo 'SYSTEM START: PREPARING SSH'; \
/usr/sbin/sshd; \
ls -la /home/test/.ssh/; \
\"$@\" \
", "DUMMY-DUMMY-DUMMY"]

# Run tests by default (master machine role)
CMD ["bash", "-c", " \
set -eux; \
echo \"HOME DIR IS [`realpath ~/`]\"; \
echo \"WORK DIR IS [$(pwd)]\"; \
if [ ! -f /home/test/.ssh/id_rsa ]; then \
su test -c \"ssh-keygen -t rsa -f /home/test/.ssh/id_rsa -q -N ''\"; \
su test -c \"cat /home/test/.ssh/id_rsa.pub >> /home/test/.ssh/authorized_keys\"; \
chmod 600 /home/test/.ssh/authorized_keys; \
fi; \
ls -la /home/test/.ssh/; \
su test -c \"ssh-keyscan -H localhost >> /home/test/.ssh/known_hosts\"; \
su test -c \"ssh-keyscan -H 127.0.0.1 >> /home/test/.ssh/known_hosts\"; \
if [ -n \"${TEST_CFG__REMOTE_HOST:-}\" ]; then \
su test -c \"ssh-keyscan -H ${TEST_CFG__REMOTE_HOST} >> /home/test/.ssh/known_hosts\"; \
fi; \
if [ -n \"${TEST_CFG__REMOTE_SSH_KEY:-}\" ]; then \
cp \"${TEST_CFG__REMOTE_SSH_KEY}\" \"${TEST_CFG__REMOTE_SSH_KEY}_ci\"; \
export TEST_CFG__REMOTE_SSH_KEY=\"${TEST_CFG__REMOTE_SSH_KEY}_ci\"; \
chown test:test \"${TEST_CFG__REMOTE_SSH_KEY}\"; \
chmod 600 \"${TEST_CFG__REMOTE_SSH_KEY}\"; \
ls -la /home/test/.ssh/; \
fi; \
ls -la ./; \
su test -c \"TEST_FILTER='' PATH=\"/home/test/.pyenv/bin:$PATH\" bash ./run_tests2.sh\"; \
"]
Loading