fetch the secrets unit's store leaves concurrently and log how long each phase takes
This commit is contained in:
parent
23c2527199
commit
197caa1e52
3 changed files with 268 additions and 9 deletions
|
|
@ -24,7 +24,7 @@ setup() {
|
|||
mkdir "$dir/kv" "$dir/clients"
|
||||
export FAKE_BAO_KV=$dir/kv FAKE_BAO_LOG=$dir/bao.log FAKE_BAO_LOGIN_RC=0
|
||||
export FAKE_AUTHELIA_LOG=$dir/authelia.log
|
||||
unset FAKE_BAO_DENY_READ FAKE_BAO_DENY_WRITE FAKE_BAO_RACE FAKE_AUTHELIA_EMPTY FAKE_AUTHELIA_NODIGEST
|
||||
unset FAKE_BAO_DENY_READ FAKE_BAO_DENY_WRITE FAKE_BAO_RACE FAKE_AUTHELIA_EMPTY FAKE_AUTHELIA_NODIGEST PREFETCH
|
||||
: >"$FAKE_BAO_LOG"
|
||||
: >"$FAKE_AUTHELIA_LOG"
|
||||
clients=$dir/clients
|
||||
|
|
@ -34,7 +34,8 @@ setup() {
|
|||
}
|
||||
|
||||
# run <function> — the function for $id and $leaf, with the stubs first on
|
||||
# PATH, after the store login the units make first. Sets $rc and $minted.
|
||||
# PATH, after the store login the units make first and, when $PREFETCH is set,
|
||||
# `store_prefetch` of the leaf. Sets $rc and $minted.
|
||||
run() {
|
||||
minted=$(
|
||||
set -e
|
||||
|
|
@ -45,6 +46,7 @@ run() {
|
|||
clients=$dir/clients
|
||||
store_init
|
||||
store_login 2>>"$dir/err"
|
||||
[ -z "${PREFETCH-}" ] || store_prefetch "$leaf" 2>>"$dir/err"
|
||||
rc=0
|
||||
"$1" "$id" "$leaf" 2>>"$dir/err" >>"$dir/out" || rc=$?
|
||||
echo "${MINTED-}"
|
||||
|
|
@ -262,6 +264,52 @@ if [ "$(id -u)" != 0 ]; then
|
|||
digest_is ""
|
||||
fi
|
||||
|
||||
# kv_gets: how many `kv get` calls the stub logged.
|
||||
kv_gets() {
|
||||
grep -c '^kv get' "$FAKE_BAO_LOG" || true
|
||||
}
|
||||
|
||||
setup "prefetch: a client the store and the disk both hold is left alone after one read"
|
||||
PREFETCH=1
|
||||
printf 'old-secret' >"$stored"
|
||||
printf 'old-digest\n' >"$digest"
|
||||
run mint_client_secret
|
||||
expect 0
|
||||
held old-secret
|
||||
digest_is old-digest
|
||||
if ran_authelia; then fail "minted although the store held a value"; fi
|
||||
if [ "$(kv_gets)" != 1 ]; then fail "$(kv_gets) reads, wanted 1"; fi
|
||||
|
||||
setup "prefetch: a digest whose secret is gone from the store is minted again, and the read back asks the store"
|
||||
PREFETCH=1
|
||||
printf 'old-digest\n' >"$digest"
|
||||
run mint_client_secret
|
||||
expect 0
|
||||
held minted-secret
|
||||
digest_is '$pbkdf2-sha512$fake'
|
||||
if [ "$minted" != 1 ]; then fail "did not report the mint"; fi
|
||||
if [ "$(kv_gets)" != 2 ]; then fail "$(kv_gets) reads, wanted the prefetch and the read back"; fi
|
||||
|
||||
setup "prefetch: a store that refuses the read leaves the digest, mints nothing and asks to retry"
|
||||
PREFETCH=1
|
||||
printf 'old-digest\n' >"$digest"
|
||||
export FAKE_BAO_DENY_READ=1
|
||||
run mint_client_secret
|
||||
expect 2
|
||||
digest_is old-digest
|
||||
if ran_authelia; then fail "minted although the read was refused"; fi
|
||||
if grep -q '^kv put' "$FAKE_BAO_LOG"; then fail "wrote although the read was refused"; fi
|
||||
if ! logged "the store cannot be read; keeping its digest"; then fail "no keep line"; fi
|
||||
|
||||
setup "prefetch: no digest but a secret in the store gets the digest of that secret"
|
||||
PREFETCH=1
|
||||
printf 'old-secret' >"$stored"
|
||||
run mint_client_secret
|
||||
expect 0
|
||||
held old-secret
|
||||
digest_is digest-of-old-secret
|
||||
if ran_authelia; then fail "minted over the store's secret"; fi
|
||||
|
||||
if [ "$failures" != 0 ]; then
|
||||
echo "$failures of $count cases failed" >&2
|
||||
exit 1
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ let
|
|||
# `FAKE_BAO_READ_5XX` is a server error on the read. A leaf nobody wrote is
|
||||
# "No value found at <path>", status 2, as `bao kv get` answers it.
|
||||
# `FAKE_BAO_RACE` has another run create the leaf between this one's read and
|
||||
# its write. Every call is logged without the value `put` reads from stdin.
|
||||
# its write. `FAKE_BAO_READ_DELAY` holds each read that long and records, in
|
||||
# `$FAKE_BAO_KV/.peak`, how many reads were in flight with it. Every call is
|
||||
# logged without the value `put` reads from stdin.
|
||||
fakeBao = pkgs.writeShellScriptBin "bao" ''
|
||||
echo "$*" >> "$FAKE_BAO_LOG"
|
||||
case "$1 $2" in
|
||||
|
|
@ -28,6 +30,12 @@ let
|
|||
[ "''${BAO_TOKEN-}" = s.fake ] || { echo "fake bao: kv without the login's token" >&2; exit 97; }
|
||||
leaf="$FAKE_BAO_KV/$(printf '%s' "$4" | tr / _)"
|
||||
[ -z "''${FAKE_BAO_READ_TIMEOUT-}" ] || exit 124
|
||||
if [ -n "''${FAKE_BAO_READ_DELAY-}" ]; then
|
||||
touch "$FAKE_BAO_KV/.inflight.$$"
|
||||
ls "$FAKE_BAO_KV"/.inflight.* | wc -l >> "$FAKE_BAO_KV/.peak"
|
||||
sleep "$FAKE_BAO_READ_DELAY"
|
||||
rm -f "$FAKE_BAO_KV/.inflight.$$"
|
||||
fi
|
||||
[ -z "''${FAKE_BAO_READ_5XX-}" ] || { echo "Error reading secret/data/x: Error making API request. Code: 503. Errors: * Vault is sealed" >&2; exit 2; }
|
||||
[ -z "''${FAKE_BAO_DENY_READ-}" ] || { echo "fake bao: permission denied" >&2; exit 2; }
|
||||
if [ -n "''${FAKE_BAO_RACE-}" ] && [ ! -e "$FAKE_BAO_KV/.raced" ]; then
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ setup() {
|
|||
dir=$(mktemp -d)
|
||||
mkdir "$dir/kv"
|
||||
export FAKE_BAO_KV=$dir/kv FAKE_BAO_LOG=$dir/bao.log FAKE_BAO_LOGIN_RC=0
|
||||
unset FAKE_BAO_DENY_READ FAKE_BAO_DENY_WRITE FAKE_BAO_RACE FAKE_BAO_READ_TIMEOUT FAKE_BAO_READ_5XX
|
||||
unset FAKE_BAO_DENY_READ FAKE_BAO_DENY_WRITE FAKE_BAO_RACE FAKE_BAO_READ_TIMEOUT FAKE_BAO_READ_5XX FAKE_BAO_READ_DELAY PREFETCH
|
||||
: >"$FAKE_BAO_LOG"
|
||||
earlier=$dir/earlier
|
||||
minted=$dir/minted
|
||||
|
|
@ -34,7 +34,8 @@ mint() {
|
|||
printf 'minted-value\n'
|
||||
}
|
||||
|
||||
# run — `store_seeded` for $leaf and $earlier with the stub first on PATH.
|
||||
# run — `store_seeded` for $leaf and $earlier with the stub first on PATH, after
|
||||
# `store_prefetch` of the leaf when $PREFETCH is set.
|
||||
# Sets $rc and $got.
|
||||
run() {
|
||||
got=$(
|
||||
|
|
@ -45,6 +46,7 @@ run() {
|
|||
. "$HELPER"
|
||||
store_init
|
||||
store_login 2>>"$dir/err"
|
||||
[ -z "${PREFETCH-}" ] || store_prefetch "$leaf" 2>>"$dir/err"
|
||||
store_seeded "$leaf" "$earlier" mint 2>"$dir/err"
|
||||
)
|
||||
rc=$?
|
||||
|
|
@ -212,6 +214,90 @@ run
|
|||
expect 1 ""
|
||||
if ran_mint; then fail "minted with no store to hold the value"; fi
|
||||
|
||||
# kv_gets: how many `kv get` calls the stub logged.
|
||||
kv_gets() {
|
||||
grep -c '^kv get' "$FAKE_BAO_LOG" || true
|
||||
}
|
||||
|
||||
setup "prefetch: a leaf the store holds is read once, and the result is the same"
|
||||
PREFETCH=1
|
||||
printf 'stored-value' >"$stored"
|
||||
printf 'old-value\n' >"$earlier"
|
||||
run
|
||||
expect 0 stored-value
|
||||
held stored-value
|
||||
no_write
|
||||
no_mint
|
||||
if [ "$(kv_gets)" != 1 ]; then fail "$(kv_gets) reads, wanted 1"; fi
|
||||
|
||||
setup "prefetch: a leaf the store lacks is seeded from the file as without it"
|
||||
PREFETCH=1
|
||||
printf 'old-value\n' >"$earlier"
|
||||
run
|
||||
expect 0 old-value
|
||||
held old-value
|
||||
if ran_mint; then fail "minted although the file held a value"; fi
|
||||
|
||||
setup "prefetch: a refused read uses the file's value, writes nothing and prints the refusal, as without it"
|
||||
PREFETCH=1
|
||||
printf 'old-value\n' >"$earlier"
|
||||
export FAKE_BAO_DENY_READ=1 FAKE_BAO_DENY_WRITE=1
|
||||
run
|
||||
expect 0 old-value
|
||||
held ""
|
||||
no_write
|
||||
no_mint
|
||||
err_has "could not read $leaf from the swarm secret store"
|
||||
err_has "permission denied"
|
||||
|
||||
setup "prefetch: a read that times out is not treated as an absent leaf"
|
||||
PREFETCH=1
|
||||
printf 'stored-value' >"$stored"
|
||||
export FAKE_BAO_READ_TIMEOUT=1
|
||||
run
|
||||
expect 1 ""
|
||||
held stored-value
|
||||
no_write
|
||||
no_mint
|
||||
err_has "(exit status 124)"
|
||||
|
||||
setup "prefetch: a store that refuses the login reads nothing"
|
||||
PREFETCH=1
|
||||
printf 'old-value\n' >"$earlier"
|
||||
export FAKE_BAO_LOGIN_RC=1
|
||||
run
|
||||
expect 0 old-value
|
||||
if grep -q '^kv' "$FAKE_BAO_LOG"; then fail "called kv after a refused login"; fi
|
||||
|
||||
setup "prefetch: many leaves are read together, at most 8 at once, each once, and a second read of one asks the store"
|
||||
export FAKE_BAO_READ_DELAY=0.3
|
||||
many=()
|
||||
for i in $(seq 1 20); do
|
||||
many+=("secret/swarm/many/$i")
|
||||
printf 'v%s' "$i" >"$FAKE_BAO_KV/$(printf '%s' "secret/swarm/many/$i" | tr / _)"
|
||||
done
|
||||
want=$(for i in $(seq 1 20); do printf 'v%s\n' "$i"; done)
|
||||
got=$(
|
||||
set -e
|
||||
PATH="$FAKE_BAO_BIN:$PATH"
|
||||
unset BAO_TOKEN
|
||||
# shellcheck source=/dev/null
|
||||
. "$HELPER"
|
||||
store_init
|
||||
store_login
|
||||
store_prefetch "${many[@]}"
|
||||
for l in "${many[@]}"; do
|
||||
store_read "$l"
|
||||
echo
|
||||
done
|
||||
store_read "${many[0]}"
|
||||
)
|
||||
if [ "$got" != "$want"$'\n'v1 ]; then fail "values differ: $got"; fi
|
||||
if [ "$(kv_gets)" != 21 ]; then fail "$(kv_gets) reads, wanted 20 and the second read of one"; fi
|
||||
peak=$(sort -n "$FAKE_BAO_KV/.peak" | tail -1)
|
||||
if [ "$peak" -gt 8 ]; then fail "$peak reads in flight, wanted at most 8"; fi
|
||||
if [ "$peak" -lt 2 ]; then fail "$peak read in flight, the reads did not overlap"; fi
|
||||
|
||||
if [ "$failures" != 0 ]; then
|
||||
echo "$failures of $count cases failed" >&2
|
||||
exit 1
|
||||
|
|
|
|||
Loading…
Reference in a new issue