etcd-client 0.21.1

An etcd v3 API client
Documentation
# etcd of the version you want for the development and the tests, it needs docker compose.

versions := "v3.5.26 v3.6.15 v3.7.2"

# List all tasks
default:
    @just --list

# Start a single etcd in the background. The user root/rootpwd exists, the tests enable the auth by themselves
etcd version="v3.7.2" max_request_bytes="1572864":
    #!/usr/bin/env bash
    set -euo pipefail
    export ETCD_VERSION={{version}} ETCD_MAX_REQUEST_BYTES={{max_request_bytes}}
    docker compose --profile single up -d --remove-orphans
    for _ in $(seq 60); do
        docker compose exec -T etcd etcdctl endpoint health >/dev/null 2>&1 && break
        sleep 1
    done
    docker compose exec -T etcd etcdctl endpoint health >/dev/null || { docker compose logs --tail 20 etcd >&2; exit 1; }
    docker compose exec -T etcd etcdctl user add root --new-user-password=rootpwd
    docker compose exec -T etcd etcdctl user grant-role root root
    echo "etcd {{version}} is up on localhost:2379"

# Start a cluster of 3 etcd nodes in the background, node1 is on localhost:2379
etcd-cluster version="v3.7.2":
    #!/usr/bin/env bash
    set -euo pipefail
    export ETCD_VERSION={{version}}
    docker compose --profile cluster up -d --remove-orphans
    for _ in $(seq 60); do
        docker compose exec -T node1 etcdctl endpoint health --cluster >/dev/null 2>&1 && break
        sleep 1
    done
    docker compose exec -T node1 etcdctl endpoint health --cluster >/dev/null || { docker compose logs --tail 20 >&2; exit 1; }
    # member add right after startup is rejected with "unhealthy cluster" until the peers settle
    sleep 10
    echo "etcd {{version}} cluster is up, node1 is on localhost:2379"

# Wait until `test_cluster` adds node4 as a member, then start it
etcd-join version="v3.7.2":
    #!/usr/bin/env bash
    set -euo pipefail
    export ETCD_VERSION={{version}}
    for _ in $(seq 120); do
        if docker compose exec -T node1 etcdctl member list | grep -q http://node4:2380; then
            # The member is registered with its peer url before it is started.
            docker compose --profile join up -d node4
            exit 0
        fi
        sleep 1
    done
    echo "node4 was never added" >&2
    exit 1

# Stop and remove the etcd containers, their data is removed with them
etcd-down:
    @docker compose --profile single --profile cluster --profile join down -v --remove-orphans

# Run the tests on a single etcd of the version
test version="v3.7.2":
    #!/usr/bin/env bash
    set -euo pipefail
    trap 'just etcd-down' EXIT
    just etcd {{version}}
    cargo test

# Run the etcd 3.7 RangeStream tests, the server splits the responses for the small max-request-bytes
test-stream version="v3.7.2":
    #!/usr/bin/env bash
    set -euo pipefail
    trap 'just etcd-down' EXIT
    just etcd {{version}} 10240
    cargo test --test client test_get_stream -- --ignored

# Run the cluster test on a cluster of the version
test-cluster version="v3.7.2":
    #!/usr/bin/env bash
    set -euo pipefail
    trap 'just etcd-down' EXIT
    just etcd-cluster {{version}}
    just etcd-join {{version}} &
    cargo test --test client test_cluster -- --ignored
    wait

# Run all the tests on every etcd version, like the CI does
test-all:
    #!/usr/bin/env bash
    set -uo pipefail
    status=0
    for v in {{versions}}; do
        echo "=== etcd $v ==="
        just test $v || status=1
        just test-cluster $v || status=1
    done
    echo "=== etcd v3.7.2, small max-request-bytes ==="
    just test-stream v3.7.2 || status=1
    exit $status