From: Kirill Isakov Date: Sat, 28 May 2022 12:27:09 +0000 (+0600) Subject: CI: add backwards compatibility checks X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=commitdiff_plain;h=41c83ed14fa28a723d666ff8dc8971d67abee276 CI: add backwards compatibility checks --- diff --git a/.ci/compat/run.sh b/.ci/compat/run.sh new file mode 100755 index 00000000..83bfedb8 --- /dev/null +++ b/.ci/compat/run.sh @@ -0,0 +1,259 @@ +#!/bin/bash + +# Three nodes are initialized: +# latest : created from the latest commit that triggered this CI job +# tinc11 : from the latest tag in tinc 1.1 branch +# tinc10 : from the latest commit in tinc 1.0 branch +# +# The latter two are configured by using import/export/exchange. +# Since tinc 1.0 doesn't support that, host configs are copied to its hosts directory. +# Then nodes are connected and some light testing is performed to make sure they work together. + +set -euo pipefail + +nodes='latest tinc11 tinc10' +total_nodes=3 + +declare -A refs=( + [tinc10]='origin/master' + [tinc11]="$(git describe --abbrev=0 --match='release-*')" + [latest]='HEAD' +) + +declare -A addr=( + [tinc10]='192.168.1.1' + [tinc11]='192.168.1.2' + [latest]='192.168.1.3' +) + +src=/usr/local/src +etc=/usr/local/etc + +mkdir -p $src $etc + +archive() { + tar -caf /tmp/tests.tar.gz /usr/local/etc || true +} + +header() { + echo >&2 '################################################################################' + echo >&2 "# $*" + echo >&2 '################################################################################' +} + +build_meson() { + meson setup "$1" -D prefix="/opt/$1" + meson install -C "$1" +} + +build_autotools() { + autoreconf -fsi + ./configure --prefix="/opt/$1" + make -j"$(nproc)" + make install +} + +build() { + local ref="$1" + header "Building tinc (ref $ref)" + + git clone "$PWD" "$src/$ref" -b "compat-$ref" + pushd "$src/$ref" + + if [[ -f meson.build ]]; then + build_meson "$ref" + else + build_autotools "$ref" + fi + + popd + mkdir -p "/opt/$ref/var/run" +} + +wait_network() { + local from="$1" + local to="$2" + local total=0 + + while ! ip netns exec "$from" ping -W1 -c1 "${addr[$to]}" >/dev/null; do + total=$((total + 1)) + + if [[ total -gt 60 ]]; then + echo >&2 "Network connection between $from and $to is not working" + exit 1 + fi + + echo >&2 "Network isn't ready yet..." + sleep 1 + done +} + +test_network() { + local from="$1" + local to="$2" + + wait_network "$from" "$to" + + header "Sending data between $from and $to" + + ip netns exec "$from" \ + iperf3 --time 1 --client "${addr[$to]}" +} + +test_sign_verify() { + local signer="$1" + local verifier="$2" + local output="$etc/$signer/signed" + + header "Test signature verification between $signer and $verifier" + + "$signer" sign >"$output" <<<"text message for node $signer to sign" + + for peer in "$signer" '*'; do + "$verifier" verify "$peer" "$output" + "$verifier" verify "$peer" <"$output" + done +} + +test_node_status() { + local node="$1" + + header "Checking node status for $node" + + reachable="$("$node" dump reachable nodes | wc -l)" + echo >&2 "Node $node can reach $reachable nodes" + + [[ $reachable == "$total_nodes" ]] + + for peer in $nodes; do + echo >&2 -n "$node info $peer: " + "$node" info "$peer" | tee /dev/stderr | grep -E -q '(can reach itself|directly)' + done +} + +latest() { + /opt/latest/sbin/tinc -c $etc/latest "$@" +} + +tinc11() { + /opt/tinc11/sbin/tinc -c $etc/tinc11 "$@" +} + +header 'Creating branches' + +for node in $nodes; do + echo >&2 " $node: $(git rev-parse "compat-$node")" + git branch "compat-$node" "${refs[$node]}" +done + +build tinc10 +build tinc11 +build latest + +header 'Initializing node from the latest commit' + +latest <$etc/tinc10/tinc.conf <$etc/tinc10/hosts/tinc10 <"$tinc_up" < latest <--> tinc11 +latest export | tinc11 exchange | latest import +cp $etc/tinc10/hosts/tinc10 $etc/latest/hosts/ +cp $etc/latest/hosts/latest $etc/tinc10/hosts/ + +header "Starting nodes" + +for node in $nodes; do + tincd="/opt/$node/sbin/tincd" + echo >&2 "Starting node $node ($tincd)" + + "$tincd" --version + + "$tincd" \ + --config "$etc/$node" \ + --pidfile "$etc/$node/pid" \ + --logfile "$etc/$node/log" \ + --debug 5 +done + +header 'Running connectivity tests' + +for client in $nodes; do + for server in $nodes; do + if [[ $client != "$server" ]]; then + test_network "$client" "$server" + fi + done +done + +test_node_status latest +test_node_status tinc11 + +test_sign_verify latest tinc11 +test_sign_verify tinc11 latest diff --git a/.ci/deps.sh b/.ci/deps.sh index 67e1e0b9..1c8293a7 100755 --- a/.ci/deps.sh +++ b/.ci/deps.sh @@ -74,6 +74,8 @@ deps_linux_debian() { } deps_linux_rhel() { + yum upgrade -y + if [ "$ID" != fedora ]; then yum install -y epel-release @@ -84,8 +86,6 @@ deps_linux_rhel() { fi fi - yum upgrade -y - yum install -y \ git binutils make meson pkgconf gcc sudo texinfo-tex systemd perl-IPC-Cmd \ lzo-devel zlib-devel lz4-devel ncurses-devel readline-devel libgcrypt-devel "$@" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 52dd0ef7..90788d71 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,5 +1,9 @@ name: Test +concurrency: + group: test-${{ github.head_ref }} + cancel-in-progress: true + on: push: pull_request: @@ -9,7 +13,7 @@ on: jobs: cross: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 30 strategy: fail-fast: false @@ -51,12 +55,21 @@ jobs: path: /tmp/logs/tests.*.tar.gz if: always() - static-analysis: - runs-on: ubuntu-latest + analysis: + runs-on: ubuntu-22.04 timeout-minutes: 30 steps: - - name: Checkout code - uses: actions/checkout@v1 + - name: Checkout tinc + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Install dependencies + run: sudo SKIP_OPENSSL3=1 .ci/deps.sh autoconf automake iperf3 + + - name: Compatibility with older versions of tinc + run: sudo ./.ci/compat/run.sh + if: always() - name: Install tools run: | @@ -72,11 +85,9 @@ jobs: pip3 install black pylint mypy env: CLANG: 11 - SHELLCHECK: 0.7.2 - SHFMT: 3.3.0 - - - name: Install deps - run: sudo SKIP_OPENSSL3=1 sh .ci/deps.sh + SHELLCHECK: 0.8.0 + SHFMT: 3.5.0 + if: always() - name: Lint/typecheck/check formatting on C/shell/Python code run: | @@ -93,11 +104,23 @@ jobs: - name: Check warnings (gcc) run: bash .ci/warn/run.sh env: - CC: gcc-10 + CC: gcc-11 + if: always() + + - name: Archive test results + run: sudo tar -caf tests.tar.gz /usr/local/etc + continue-on-error: true + if: always() + + - name: Upload test results + uses: actions/upload-artifact@v2 + with: + name: tests_compat + path: tests.tar.gz if: always() sanitizer: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 30 strategy: fail-fast: false @@ -114,7 +137,9 @@ jobs: uses: actions/checkout@v1 - name: Install deps - run: sudo sh .ci/deps.sh + run: | + sudo sh .ci/deps.sh + sudo pip3 install --upgrade cryptography - name: Run tests with OpenSSL 3 run: bash .ci/sanitizers/run.sh openssl3 @@ -140,7 +165,7 @@ jobs: if: always() linux: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 30 strategy: fail-fast: false @@ -213,7 +238,7 @@ jobs: pkg-publish: if: always() && (github.ref == 'refs/heads/1.1' || startsWith(github.ref, 'refs/tags/release-')) - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 continue-on-error: true needs: - linux @@ -248,7 +273,7 @@ jobs: if: startsWith(github.ref, 'refs/tags/') macos: - runs-on: macos-latest + runs-on: macos-12 timeout-minutes: 20 steps: