Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ dist/doc-$(VERSION).tar.gz: $(DOC_SRC) bash/bashadoc

dist/bin-$(VERSION).tar.gz: $(DOC_SRC) $(BIN_SRC) bash/pack-script
mkdir -p dist/bin
for s in $$(find bash -type f ! -name '*.sh' -exec grep -q "includer" {} \; -print); do \
for s in $$(find bash -maxdepth 1 -type f ! -name '*.sh' -perm -u+x -print); do \
base=$$(basename $$s) ; \
bash/pack-script -v -f $$s -o dist/bin/$$base ; \
if grep -q "includer" $$s; then \
bash/pack-script -v -f $$s -o dist/bin/$$base ; \
else \
cp $$s dist/bin/$$base ; \
fi ; \
done
tar -zcf dist/bin-$(VERSION).tar.gz -C dist bin
rm -rf dist/bin
Expand Down
10 changes: 8 additions & 2 deletions bash/against-each-pod
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,16 @@ LABEL=${1:?label required as first positional arg}
shift
COMMAND=${1:?subcommand required as second positional arg}
shift

NAMESPACE_ARGS=()
if [ -n "${NAMESPACE:-}" ]; then
NAMESPACE_ARGS=(-n "$NAMESPACE")
fi

for pod in $(k8s::pod_names_for_label "$LABEL" "${NAMESPACE:-}" | sort); do
node_name=$(k8s::ctl get pod "$pod" -o json |
node_name=$(k8s::ctl get pod "$pod" "${NAMESPACE_ARGS[@]}" -o json |
$(commands::use jq) -r '.spec.nodeName')
echo "=== $node_name $pod ==="
k8s::ctl "$COMMAND" "pod/$pod" "$@"
k8s::ctl "$COMMAND" "pod/$pod" "${NAMESPACE_ARGS[@]}" "$@"
echo
done
82 changes: 66 additions & 16 deletions bash/daml-export
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ function build {
echo "Building $dir"
pushd "$dir" >/dev/null || return 1
daml build >"build.log" 2>&1
local build_exit=$?
popd >/dev/null || return 1
return "$build_exit"
}

# SUR-2838 test seam: when sourced from bats, skip the main entry
Expand All @@ -182,6 +184,7 @@ STOP_INT=$(hex_to_dec "$STOP_OFFSET")

count=0
RUNNING_PROCS=()
RUNNING_OUTPUT_DIRS=()
# TO_BUILD removed (SUR-1871): the previous queue accumulated every
# OUTPUT_DIR but only drained one entry per iteration, so the post-loop
# `find ... export.good` walk below already had to pick up the rest.
Expand All @@ -192,15 +195,61 @@ RUNNING_PROCS=()
# exit or Ctrl-C so they don't keep running after the user gives up.
# `kill -0` guards against already-reaped pids, and stderr is swallowed
# so the trap stays quiet on normal completion.
function refresh_running_procs {
local idx
local pid
local current_pids=()
local current_dirs=()
for idx in "${!RUNNING_PROCS[@]}"; do
pid=${RUNNING_PROCS[$idx]}
if ps -p "$pid" >/dev/null; then
current_pids+=("$pid")
current_dirs+=("${RUNNING_OUTPUT_DIRS[$idx]}")
fi
done
RUNNING_PROCS=("${current_pids[@]}")
RUNNING_OUTPUT_DIRS=("${current_dirs[@]}")
}

function is_output_dir_running {
local dir=${1:?}
local running_dir
for running_dir in "${RUNNING_OUTPUT_DIRS[@]}"; do
if [ "$running_dir" = "$dir" ]; then
return 0
fi
done
return 1
}

function kill_running_procs {
local pid
refresh_running_procs
for pid in "${RUNNING_PROCS[@]}"; do
if kill -0 "$pid" 2>/dev/null; then
kill "$pid" 2>/dev/null || true
fi
done
}
trap kill_running_procs EXIT INT TERM

function wait_for_running_procs {
local pid
local wait_status=0
for pid in "${RUNNING_PROCS[@]}"; do
wait "$pid" || wait_status=1
done
RUNNING_PROCS=()
RUNNING_OUTPUT_DIRS=()
return "$wait_status"
}

NORMAL_COMPLETION=false
function handle_exit {
if [ "$NORMAL_COMPLETION" != "true" ]; then
kill_running_procs
fi
}
trap handle_exit EXIT INT TERM

# Loop guard rewrite (SUR-1871): the original
# while [ "$CUR_INT" -le "$STOP_INT" ] && [ "$CUR_INT" != "$NEXT_INT" ]
Expand Down Expand Up @@ -231,18 +280,13 @@ while [ "$CUR_INT" -le "$STOP_INT" ]; do
exportRange "$CUR_HEX" "$NEXT_HEX" "$OUTPUT_DIR" "$BASE_DIR"
fi

CURRENT_PROCS=()
for pid in "${RUNNING_PROCS[@]}"; do
if ps -p "$pid" >/dev/null; then
CURRENT_PROCS+=("$pid")
fi
RUNNING_PROCS=("${CURRENT_PROCS[@]}")
done
refresh_running_procs

if [ "${#RUNNING_PROCS[@]}" -lt "$MAX_PARALLEL" ]; then
correct_export "$OUTPUT_DIR"
build "$OUTPUT_DIR" &
RUNNING_PROCS+=($!)
RUNNING_OUTPUT_DIRS+=("$OUTPUT_DIR")
echo "Daml builds ${RUNNING_PROCS[*]} in the background"
fi

Expand All @@ -256,8 +300,12 @@ done
function verify_and_build() {
local buildFile=${1:?}
local OUTPUT_DIR
local CURRENT_PROCS
OUTPUT_DIR=$(dirname "$buildFile")
refresh_running_procs
if is_output_dir_running "$OUTPUT_DIR"; then
echo "Skipping $OUTPUT_DIR since a build is already running"
return
fi
verifyExport "$OUTPUT_DIR"
local ret=$?
if [ $ret -gt 1 ]; then
Expand All @@ -272,19 +320,21 @@ function verify_and_build() {

while [ "${#RUNNING_PROCS[@]}" -ge "$MAX_PARALLEL" ]; do
sleep 10
CURRENT_PROCS=()
for pid in "${RUNNING_PROCS[@]}"; do
if ps -p "$pid" >/dev/null; then
CURRENT_PROCS+=("$pid")
fi
RUNNING_PROCS=("${CURRENT_PROCS[@]}")
done
refresh_running_procs
done

build "$OUTPUT_DIR" &
RUNNING_PROCS+=($!)
RUNNING_OUTPUT_DIRS+=("$OUTPUT_DIR")
}

while read -r buildFile; do
verify_and_build "$buildFile"
done < <(find "$TARGET_DIR" -name export.good -print | sort)

wait_for_running_procs
WAIT_STATUS=$?
NORMAL_COMPLETION=true
if [ "$WAIT_STATUS" -ne 0 ]; then
exit "$WAIT_STATUS"
fi
6 changes: 5 additions & 1 deletion bash/pod-console
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ options::parse "$@"
shift $((OPTIND - 1))

SESSION=$LABEL
NAMESPACE_ARGS=()
if [ -n "${NAMESPACE:-}" ]; then
NAMESPACE_ARGS=(-n "$NAMESPACE")
fi

function tmux::cmd {
$(commands::use tmux) "$@"
Expand All @@ -57,7 +61,7 @@ for pod in $(k8s::pod_names_for_label "$LABEL" "${NAMESPACE:-}" | sort); do
# Build the send-keys payload via printf %q so each positional arg
# round-trips through the remote shell's tokeniser intact instead of
# being collapsed by IFS-joined "$*". See SUR-1869.
payload=$(printf '%q ' "$(commands::use kubectl)" "$COMMAND" "pod/$pod" "$@")
payload=$(printf '%q ' "$(commands::use kubectl)" "$COMMAND" "pod/$pod" "${NAMESPACE_ARGS[@]}" "$@")
log::debug "Execute on $SESSION: $payload"
tmux::cmd send-keys -t "$SESSION" "$payload" C-m
log::debug "Tile window $WINDOW"
Expand Down
5 changes: 5 additions & 0 deletions tests/against-each-pod.bats
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ teardown() {
[[ "$argv" == *"--field-selector=status.phase=Running"* ]]
[[ "$argv" == *"-o name"* ]]
[[ "$argv" == *"-n my-ns"* ]]
# Every kubectl call (listing, get pod, and per-pod command) must
# preserve -n when the option is provided.
while IFS= read -r line; do
[[ "$line" == *" -n my-ns "* ]] || [[ "$line" == *" -n my-ns" ]]
done <"$KUBECTL_ARGV_LOG"
}

@test "against-each-pod without -n omits namespace from kubectl argv" {
Expand Down
86 changes: 86 additions & 0 deletions tests/daml-export.bats
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,26 @@ setup() {
export DAML_EXPORT_SOURCE_ONLY=true
}

function write_daml_stub() {
local stub_bin=${1:?}
cat >"$stub_bin/daml" <<'EOF'
#!/usr/bin/env bash
if [ "$1" = "build" ]; then
echo "start:$PWD" >>"${DAML_STUB_LOG:?}"
trap 'echo "killed:$PWD" >>"${DAML_STUB_LOG:?}"; exit 143' TERM INT
sleep "${DAML_BUILD_SLEEP:-1}"
if [ -n "${DAML_BUILD_FAIL_DIR:-}" ] && [[ "$PWD" == *"${DAML_BUILD_FAIL_DIR}" ]]; then
echo "fail:$PWD" >>"${DAML_STUB_LOG:?}"
exit 7
fi
echo "done:$PWD" >>"${DAML_STUB_LOG:?}"
exit 0
fi
exit 0
EOF
chmod +x "$stub_bin/daml"
}

@test "DAML_EXPORT_SOURCE_ONLY exits 0 when executed (no main body) (SUR-2838)" {
out=$(mktemp -d)
run env DAML_EXPORT_SOURCE_ONLY=true bash "$DAML_EXPORT" -d "$out" -e ffff
Expand Down Expand Up @@ -164,3 +184,69 @@ EOF
grep -q "^archiveCmd foo$" "$tmp/Export.daml"
rm -rf "$tmp"
}

@test "daml-export waits for in-flight background builds on normal exit (SUR-3352)" {
tmp=$(mktemp -d)
stub_bin=$(mktemp -d)
log_file=$(mktemp)
write_daml_stub "$stub_bin"

dir="$tmp/0000000000000000-0000000000000001"
mkdir -p "$dir"
touch "$dir/export.good" "$dir/Export.daml"
cat >"$dir/daml.yaml" <<'EOF'
build-options: ["--target=1.14"]
EOF

run env PATH="$stub_bin:$PATH" DAML_STUB_LOG="$log_file" DAML_BUILD_SLEEP=1 DAML_EXPORT_SOURCE_ONLY= \
bash "$DAML_EXPORT" -d "$tmp" -b 0 -e 1 -s 1 -P 5
[ "$status" -eq 0 ]
[[ "$(cat "$log_file")" == *"done:$dir"* ]]
run ! grep -q "^killed:" "$log_file"
rm -rf "$tmp" "$stub_bin"
rm -f "$log_file"
}

@test "daml-export propagates background build failure to exit status (SUR-3352)" {
tmp=$(mktemp -d)
stub_bin=$(mktemp -d)
log_file=$(mktemp)
write_daml_stub "$stub_bin"

dir="$tmp/0000000000000000-0000000000000001"
mkdir -p "$dir"
touch "$dir/export.good" "$dir/Export.daml"
cat >"$dir/daml.yaml" <<'EOF'
build-options: ["--target=1.14"]
EOF

run env PATH="$stub_bin:$PATH" DAML_STUB_LOG="$log_file" DAML_BUILD_SLEEP=1 DAML_EXPORT_SOURCE_ONLY= \
DAML_BUILD_FAIL_DIR="0000000000000000-0000000000000001" \
bash "$DAML_EXPORT" -d "$tmp" -b 0 -e 1 -s 1 -P 5
[ "$status" -ne 0 ]
[[ "$(cat "$log_file")" == *"fail:$dir"* ]]
rm -rf "$tmp" "$stub_bin"
rm -f "$log_file"
}

@test "daml-export does not schedule duplicate builds for same output dir (SUR-3352)" {
tmp=$(mktemp -d)
stub_bin=$(mktemp -d)
log_file=$(mktemp)
write_daml_stub "$stub_bin"

dir="$tmp/0000000000000000-0000000000000001"
mkdir -p "$dir"
touch "$dir/export.good" "$dir/Export.daml"
cat >"$dir/daml.yaml" <<'EOF'
build-options: ["--target=1.14"]
EOF

run env PATH="$stub_bin:$PATH" DAML_STUB_LOG="$log_file" DAML_BUILD_SLEEP=1 DAML_EXPORT_SOURCE_ONLY= \
bash "$DAML_EXPORT" -d "$tmp" -b 0 -e 1 -s 1 -P 5
[ "$status" -eq 0 ]
starts=$(grep -c "^start:$dir" "$log_file" || true)
[ "$starts" -eq 1 ]
rm -rf "$tmp" "$stub_bin"
rm -f "$log_file"
}
21 changes: 21 additions & 0 deletions tests/package.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bats
bats_require_minimum_version 1.5.0

setup() {
load 'helpers.bash'
helpers::isolate_home
}

@test "bin package includes standalone executable commands mddoc and semver (SUR-3353)" {
run make clean package
[ "$status" -eq 0 ]

version=$(make --no-print-directory what_version | awk -F= '/^VERSION=/{print $2}')
tarball="$REPO_ROOT/dist/bin-$version.tar.gz"
[ -f "$tarball" ]

run tar -tzf "$tarball"
[ "$status" -eq 0 ]
[[ "$output" == *"bin/mddoc"* ]]
[[ "$output" == *"bin/semver"* ]]
}
14 changes: 14 additions & 0 deletions tests/pod-console.bats
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@ teardown() {
[ "${!#}" = 'echo "two words"' ]
}

@test "send-keys payload includes namespace when -n is provided" {
run "$REPO_ROOT/bash/pod-console" -n my-ns -l app=foo -c exec -- sh -c "true"
[ "$status" -eq 0 ]

send_line=$(grep -a '^send-keys' "$TMUX_ARGV_LOG" | tr '\0' '\n')
[ -n "$send_line" ]
payload=$(awk 'NR==4 {print; exit}' <<<"$send_line")
[ -n "$payload" ]

eval "set -- $payload"
joined=" $* "
[[ "$joined" == *" -n my-ns "* ]]
}

@test "no \$* expansion remains in pod-console (excluding comments)" {
# Strip comment-only and trailing-comment content before matching, so
# any commentary that mentions the historical bug does not trip the
Expand Down
Loading