mirror of
https://github.com/logos-storage/logos-storage-nim.git
synced 2026-06-26 12:29:30 +00:00
703 lines
19 KiB
Bash
Executable File
703 lines
19 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
|
|
REMOTE_SSH_HOST="${REMOTE_SSH_HOST:-storage@172.235.163.25}"
|
|
REMOTE_API_PORT="${REMOTE_API_PORT:-18080}"
|
|
LOCAL_API_PORT="${LOCAL_API_PORT:-8080}"
|
|
TUNNEL_CONTROL_PATH="${TUNNEL_CONTROL_PATH:-/tmp/logos-storage-tunnel-${USER:-user}.ctl}"
|
|
CID_STATE_FILE="${CID_STATE_FILE:-${HOME}/.logos/storage/test/cids.log}"
|
|
TEST_FILES_DIR="${TEST_FILES_DIR:-${HOME}/.logos/storage/test/files}"
|
|
TEST_FILE_SIZES="${TEST_FILE_SIZES:-4K 1M 10M}"
|
|
TEST_KEEP_FILES="${TEST_KEEP_FILES:-0}"
|
|
STORAGE_LIB_CTL="${STORAGE_LIB_CTL:-${ROOT_DIR}/tools/libstorage-cpp/storage_lib_ctl}"
|
|
STORAGE_LIB_SOCKET="${STORAGE_LIB_SOCKET:-${HOME}/.logos/storage/libstorage/storage_lib.sock}"
|
|
|
|
LOCAL_API="http://127.0.0.1:${LOCAL_API_PORT}/api/storage/v1"
|
|
REMOTE_API="http://127.0.0.1:${REMOTE_API_PORT}/api/storage/v1"
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $0 <target> <command> [args]
|
|
$0 <global-command> [args]
|
|
|
|
Targets:
|
|
local Local REST node at $LOCAL_API
|
|
remote Remote REST node through SSH tunnel at $REMOTE_API
|
|
lib Local storage_lib daemon via Unix socket
|
|
|
|
Target commands:
|
|
<target> upload <file>
|
|
Upload a file and print the returned CID.
|
|
|
|
<target> upload-random <size> [--keep]
|
|
Create random content, upload it, print CID.
|
|
|
|
<target> download <cid> <output-file> [--local]
|
|
Download CID into output-file. For lib, --local means local store only.
|
|
|
|
<target> fetch <cid> [--wait]
|
|
Fetch CID from network into target local store. --wait is REST-only.
|
|
|
|
<target> list
|
|
List manifest CIDs stored locally by target.
|
|
|
|
<target> delete <cid>
|
|
Delete CID from target local storage.
|
|
|
|
<target> delete-all --yes
|
|
Delete every CID returned by list from target local storage.
|
|
|
|
<target> exists <cid>
|
|
Check whether target has CID locally.
|
|
|
|
<target> space
|
|
Show target storage space information.
|
|
|
|
<target> peerid
|
|
Show target peer ID.
|
|
|
|
<target> test
|
|
Upload random files to remote, download via local/lib target, validate hashes,
|
|
and clean up involved CIDs. Supported targets: local, lib.
|
|
|
|
Lib-only target commands:
|
|
lib spr
|
|
lib debug
|
|
lib manifest <cid>
|
|
lib connect <peer-id> [addr...]
|
|
|
|
Global commands:
|
|
help
|
|
Show this help.
|
|
|
|
tunnel start|stop|status
|
|
Manage SSH tunnel to the remote REST API.
|
|
|
|
make-file <size> [output-file]
|
|
Create random content with dd. Example: make-file 10M /tmp/logos-10M.bin
|
|
|
|
last-cid [target]
|
|
Print the most recent CID from CID_STATE_FILE, optionally filtered by target.
|
|
|
|
Environment:
|
|
REMOTE_SSH_HOST SSH host for the remote node [$REMOTE_SSH_HOST]
|
|
REMOTE_API_PORT Local tunnel port for remote API [$REMOTE_API_PORT]
|
|
LOCAL_API_PORT Local node API port [$LOCAL_API_PORT]
|
|
STORAGE_LIB_CTL Path to storage_lib_ctl [$STORAGE_LIB_CTL]
|
|
STORAGE_LIB_SOCKET Unix socket for storage_lib [$STORAGE_LIB_SOCKET]
|
|
CID_STATE_FILE Upload history log [$CID_STATE_FILE]
|
|
TEST_FILES_DIR Generated test file directory [$TEST_FILES_DIR]
|
|
TEST_FILE_SIZES Sizes used by '<target> test' [$TEST_FILE_SIZES]
|
|
TEST_KEEP_FILES Keep test workspace when set to 1 [$TEST_KEEP_FILES]
|
|
|
|
Examples:
|
|
$0 tunnel start
|
|
$0 remote upload-random 10M
|
|
$0 local fetch <CID> --wait
|
|
$0 local download <CID> /tmp/downloaded.bin
|
|
$0 lib download <CID> /tmp/downloaded.bin
|
|
$0 lib test
|
|
$0 local test
|
|
EOF
|
|
}
|
|
|
|
die() {
|
|
printf 'error: %s\n' "$*" >&2
|
|
exit 1
|
|
}
|
|
|
|
need() {
|
|
command -v "$1" >/dev/null 2>&1 || die "missing required command: $1"
|
|
}
|
|
|
|
check_common_deps() {
|
|
need curl
|
|
need jq
|
|
}
|
|
|
|
is_target() {
|
|
case "${1:-}" in
|
|
local|remote|lib) return 0 ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
|
|
target_api() {
|
|
case "${1:-}" in
|
|
local)
|
|
printf '%s\n' "$LOCAL_API"
|
|
;;
|
|
remote)
|
|
tunnel_start >/dev/null
|
|
printf '%s\n' "$REMOTE_API"
|
|
;;
|
|
*)
|
|
die "REST target must be 'local' or 'remote'"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
tunnel_status() {
|
|
ssh -S "$TUNNEL_CONTROL_PATH" -O check "$REMOTE_SSH_HOST" >/dev/null 2>&1
|
|
}
|
|
|
|
tunnel_start() {
|
|
need ssh
|
|
if tunnel_status; then
|
|
printf 'tunnel already running: 127.0.0.1:%s -> %s:127.0.0.1:8080\n' \
|
|
"$REMOTE_API_PORT" "$REMOTE_SSH_HOST"
|
|
return 0
|
|
fi
|
|
|
|
ssh \
|
|
-M \
|
|
-S "$TUNNEL_CONTROL_PATH" \
|
|
-fN \
|
|
-L "127.0.0.1:${REMOTE_API_PORT}:127.0.0.1:8080" \
|
|
"$REMOTE_SSH_HOST"
|
|
|
|
printf 'started tunnel: 127.0.0.1:%s -> %s:127.0.0.1:8080\n' \
|
|
"$REMOTE_API_PORT" "$REMOTE_SSH_HOST"
|
|
}
|
|
|
|
tunnel_stop() {
|
|
need ssh
|
|
if tunnel_status; then
|
|
ssh -S "$TUNNEL_CONTROL_PATH" -O exit "$REMOTE_SSH_HOST" >/dev/null
|
|
printf 'stopped tunnel\n'
|
|
else
|
|
printf 'tunnel not running\n'
|
|
fi
|
|
}
|
|
|
|
make_file() {
|
|
local size="${1:-}"
|
|
local out="${2:-}"
|
|
[[ -n "$size" ]] || die 'make-file requires <size>'
|
|
if [[ -z "$out" ]]; then
|
|
mkdir -p "$TEST_FILES_DIR"
|
|
out="${TEST_FILES_DIR}/logos-test-${size}-$(date -u +%Y%m%dT%H%M%SZ).bin"
|
|
fi
|
|
dd if=/dev/urandom of="$out" bs="$size" count=1 status=progress
|
|
printf '%s\n' "$out"
|
|
}
|
|
|
|
record_cid() {
|
|
local target="$1"
|
|
local cid="$2"
|
|
local file="$3"
|
|
mkdir -p "$(dirname "$CID_STATE_FILE")"
|
|
printf '%s %s %s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$target" "$cid" "$file" >> "$CID_STATE_FILE"
|
|
}
|
|
|
|
last_cid() {
|
|
local target=""
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
local|remote|lib)
|
|
[[ -z "$target" ]] || die 'target specified more than once'
|
|
target="$1"
|
|
;;
|
|
*)
|
|
die "unknown last-cid option: $1"
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
[[ -f "$CID_STATE_FILE" ]] || die "CID state file not found: $CID_STATE_FILE"
|
|
|
|
local cid
|
|
if [[ -n "$target" ]]; then
|
|
cid="$(awk -v target="$target" '$2 == target { cid = $3 } END { print cid }' "$CID_STATE_FILE")"
|
|
else
|
|
cid="$(awk 'NF >= 3 { cid = $3 } END { print cid }' "$CID_STATE_FILE")"
|
|
fi
|
|
|
|
[[ -n "$cid" ]] || die 'no matching CID found'
|
|
printf '%s\n' "$cid"
|
|
}
|
|
|
|
lib_ctl_raw() {
|
|
[[ -x "$STORAGE_LIB_CTL" ]] || die "storage_lib_ctl not executable: $STORAGE_LIB_CTL"
|
|
"$STORAGE_LIB_CTL" --socket "$STORAGE_LIB_SOCKET" "$@"
|
|
}
|
|
|
|
lib_result() {
|
|
check_common_deps
|
|
local response
|
|
response="$(lib_ctl_raw "$@")"
|
|
if ! printf '%s\n' "$response" | jq -e '.ok == true' >/dev/null; then
|
|
printf '%s\n' "$response" >&2
|
|
return 1
|
|
fi
|
|
printf '%s\n' "$response" | jq -r '.result'
|
|
}
|
|
|
|
abs_existing_path() {
|
|
local path="$1"
|
|
[[ -e "$path" ]] || die "path not found: $path"
|
|
local dir base
|
|
dir="$(cd "$(dirname "$path")" && pwd)"
|
|
base="$(basename "$path")"
|
|
printf '%s/%s\n' "$dir" "$base"
|
|
}
|
|
|
|
abs_output_path() {
|
|
local path="$1"
|
|
local dir base
|
|
dir="$(dirname "$path")"
|
|
base="$(basename "$path")"
|
|
mkdir -p "$dir"
|
|
dir="$(cd "$dir" && pwd)"
|
|
printf '%s/%s\n' "$dir" "$base"
|
|
}
|
|
|
|
rest_upload_file() {
|
|
check_common_deps
|
|
local target="$1"
|
|
local file="$2"
|
|
[[ -f "$file" ]] || die "file not found: $file"
|
|
local api
|
|
api="$(target_api "$target")"
|
|
curl -fsS \
|
|
-H 'Content-Type: application/octet-stream' \
|
|
--data-binary "@${file}" \
|
|
"${api}/data"
|
|
}
|
|
|
|
target_upload_file() {
|
|
local target="$1"
|
|
local file="$2"
|
|
[[ -n "$file" ]] || die 'upload requires <file>'
|
|
local cid
|
|
if [[ "$target" == 'lib' ]]; then
|
|
cid="$(lib_result upload "$(abs_existing_path "$file")")"
|
|
else
|
|
cid="$(rest_upload_file "$target" "$file")"
|
|
fi
|
|
printf '%s\n' "$cid"
|
|
record_cid "$target" "$cid" "$file"
|
|
}
|
|
|
|
target_upload_random() {
|
|
local target="$1"
|
|
local size="${2:-}"
|
|
local keep=false
|
|
[[ -n "$size" ]] || die 'upload-random requires <size> [--keep]'
|
|
|
|
shift 2
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--keep) keep=true ;;
|
|
*) die "unknown upload-random option: $1" ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
local tmp cid
|
|
tmp="$(mktemp "${TMPDIR:-/tmp}/logos-storage-test.XXXXXX")"
|
|
dd if=/dev/urandom of="$tmp" bs="$size" count=1 status=progress >&2
|
|
cid="$(target_upload_file "$target" "$tmp")"
|
|
printf '%s\n' "$cid"
|
|
|
|
if [[ "$keep" == true ]]; then
|
|
printf 'kept file: %s\n' "$tmp" >&2
|
|
else
|
|
rm -f "$tmp"
|
|
fi
|
|
}
|
|
|
|
target_list_cids() {
|
|
local target="$1"
|
|
if [[ "$target" == 'lib' ]]; then
|
|
lib_result list | jq -r '.[]?.cid'
|
|
return 0
|
|
fi
|
|
|
|
check_common_deps
|
|
local api
|
|
api="$(target_api "$target")"
|
|
curl -fsS "${api}/data" | jq -r '.content[]?.cid'
|
|
}
|
|
|
|
target_delete_cid() {
|
|
local target="$1"
|
|
local cid="${2:-}"
|
|
[[ -n "$cid" ]] || die 'delete requires <cid>'
|
|
if [[ "$target" == 'lib' ]]; then
|
|
lib_result delete "$cid" >/dev/null
|
|
else
|
|
check_common_deps
|
|
local api
|
|
api="$(target_api "$target")"
|
|
curl -fsS -X DELETE "${api}/data/${cid}" >/dev/null
|
|
fi
|
|
printf 'deleted %s from %s\n' "$cid" "$target"
|
|
}
|
|
|
|
target_delete_all() {
|
|
local target="$1"
|
|
local yes="${2:-}"
|
|
[[ "$yes" == '--yes' ]] || die 'delete-all requires --yes'
|
|
|
|
local cid count=0
|
|
while IFS= read -r cid; do
|
|
[[ -n "$cid" ]] || continue
|
|
target_delete_cid "$target" "$cid"
|
|
count=$((count + 1))
|
|
done < <(target_list_cids "$target")
|
|
printf 'deleted %d CID(s) from %s\n' "$count" "$target"
|
|
}
|
|
|
|
target_simple_get() {
|
|
local target="$1"
|
|
local path="$2"
|
|
if [[ "$target" == 'lib' ]]; then
|
|
case "$path" in
|
|
space) lib_result space ;;
|
|
peerid) lib_result peer-id ;;
|
|
*) die "unsupported lib get path: $path" ;;
|
|
esac
|
|
return 0
|
|
fi
|
|
|
|
check_common_deps
|
|
local api
|
|
api="$(target_api "$target")"
|
|
curl -fsS "${api}/${path}"
|
|
printf '\n'
|
|
}
|
|
|
|
target_exists_cid() {
|
|
local target="$1"
|
|
local cid="${2:-}"
|
|
[[ -n "$cid" ]] || die 'exists requires <cid>'
|
|
if [[ "$target" == 'lib' ]]; then
|
|
lib_result exists "$cid"
|
|
else
|
|
target_simple_get "$target" "data/${cid}/exists"
|
|
fi
|
|
}
|
|
|
|
target_fetch_cid() {
|
|
local target="$1"
|
|
local cid="${2:-}"
|
|
local wait="${3:-}"
|
|
[[ -n "$cid" ]] || die 'fetch requires <cid> [--wait]'
|
|
[[ -z "$wait" || "$wait" == '--wait' ]] || die 'only supported option is --wait'
|
|
|
|
if [[ "$target" == 'lib' ]]; then
|
|
[[ -z "$wait" ]] || printf 'warning: --wait is ignored for lib fetch\n' >&2
|
|
lib_result fetch "$cid"
|
|
return 0
|
|
fi
|
|
|
|
check_common_deps
|
|
local api response download_id
|
|
api="$(target_api "$target")"
|
|
response="$(curl -fsS -X POST "${api}/data/${cid}/network")"
|
|
printf '%s\n' "$response" | jq .
|
|
|
|
if [[ "$wait" != '--wait' ]]; then
|
|
return 0
|
|
fi
|
|
|
|
download_id="$(printf '%s\n' "$response" | jq -r '.downloadId // empty')"
|
|
[[ -n "$download_id" ]] || die 'response did not contain downloadId'
|
|
|
|
while true; do
|
|
local progress active received total
|
|
progress="$(curl -fsS "${api}/data/${cid}/network/progress/${download_id}")"
|
|
printf '%s\n' "$progress" | jq .
|
|
active="$(printf '%s\n' "$progress" | jq -r '.active')"
|
|
received="$(printf '%s\n' "$progress" | jq -r '.received // 0')"
|
|
total="$(printf '%s\n' "$progress" | jq -r '.total // 0')"
|
|
if [[ "$active" != 'true' || ( "$total" != '0' && "$received" == "$total" ) ]]; then
|
|
break
|
|
fi
|
|
sleep 2
|
|
done
|
|
}
|
|
|
|
target_download_cid() {
|
|
local target="$1"
|
|
local cid="${2:-}"
|
|
local out="${3:-}"
|
|
local local_only=false
|
|
[[ -n "$cid" && -n "$out" ]] || die 'download requires <cid> <output-file> [--local]'
|
|
if [[ "${4:-}" == '--local' ]]; then
|
|
local_only=true
|
|
elif [[ -n "${4:-}" ]]; then
|
|
die 'download only supports optional --local'
|
|
fi
|
|
|
|
if [[ "$target" == 'lib' ]]; then
|
|
lib_result download "$cid" "$(abs_output_path "$out")" "$local_only" >/dev/null
|
|
else
|
|
check_common_deps
|
|
local api
|
|
api="$(target_api "$target")"
|
|
curl -fL "${api}/data/${cid}/network/stream" -o "$out"
|
|
fi
|
|
printf '%s\n' "$out"
|
|
}
|
|
|
|
lib_only_command() {
|
|
local command="$1"
|
|
shift
|
|
case "$command" in
|
|
spr|debug)
|
|
[[ $# -eq 0 ]] || die "$command does not accept arguments"
|
|
lib_result "$command"
|
|
;;
|
|
manifest)
|
|
[[ $# -eq 1 ]] || die 'manifest requires <cid>'
|
|
lib_result manifest "$1"
|
|
;;
|
|
connect)
|
|
[[ $# -ge 1 ]] || die 'connect requires <peer-id> [addr...]'
|
|
lib_result connect "$@"
|
|
;;
|
|
*)
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
size_to_bytes() {
|
|
local value="$1"
|
|
local number suffix
|
|
number="${value%[KkMmGg]}"
|
|
suffix="${value:${#number}}"
|
|
[[ "$number" =~ ^[0-9]+$ ]] || die "invalid size: $value"
|
|
case "$suffix" in
|
|
K|k) printf '%s\n' $((number * 1024)) ;;
|
|
M|m) printf '%s\n' $((number * 1024 * 1024)) ;;
|
|
G|g) printf '%s\n' $((number * 1024 * 1024 * 1024)) ;;
|
|
'') printf '%s\n' "$number" ;;
|
|
*) die "invalid size suffix: $value" ;;
|
|
esac
|
|
}
|
|
|
|
target_test() {
|
|
local target="$1"
|
|
[[ "$target" == 'local' || "$target" == 'lib' ]] || die 'test is supported only for local and lib targets'
|
|
check_common_deps
|
|
need sha256sum
|
|
|
|
local max_bytes=$((10 * 1024 * 1024))
|
|
local workspace report_ts report_path start_time start_epoch cleanup_done=0 cleanup_failures=0
|
|
workspace="$(mktemp -d "${TMPDIR:-/tmp}/logos-storage-test.XXXXXX")"
|
|
report_ts="$(date +%Y-%m-%d_%H-%M-%S)"
|
|
report_path="./report-${report_ts}.md"
|
|
start_time="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
start_epoch="$(date +%s)"
|
|
local -a cids=()
|
|
local -a local_cids=()
|
|
local -a result_sizes=()
|
|
local -a result_bytes=()
|
|
local -a result_sources=()
|
|
local -a result_downloads=()
|
|
local -a result_cids=()
|
|
local -a result_hashes=()
|
|
local -a cleanup_messages=()
|
|
|
|
cleanup() {
|
|
if [[ "$cleanup_done" == '1' ]]; then
|
|
return 0
|
|
fi
|
|
cleanup_done=1
|
|
local cid
|
|
for cid in "${local_cids[@]:-}"; do
|
|
if target_delete_cid "$target" "$cid" >/dev/null 2>&1; then
|
|
cleanup_messages+=("deleted $cid from $target")
|
|
else
|
|
cleanup_messages+=("failed to delete $cid from $target")
|
|
cleanup_failures=$((cleanup_failures + 1))
|
|
fi
|
|
done
|
|
for cid in "${cids[@]:-}"; do
|
|
if target_delete_cid remote "$cid" >/dev/null 2>&1; then
|
|
cleanup_messages+=("deleted $cid from remote")
|
|
else
|
|
cleanup_messages+=("failed to delete $cid from remote")
|
|
cleanup_failures=$((cleanup_failures + 1))
|
|
fi
|
|
done
|
|
if [[ "$TEST_KEEP_FILES" != '1' ]]; then
|
|
rm -rf "$workspace"
|
|
cleanup_messages+=("removed workspace $workspace")
|
|
else
|
|
printf 'kept test workspace: %s\n' "$workspace" >&2
|
|
cleanup_messages+=("kept workspace $workspace")
|
|
fi
|
|
}
|
|
trap cleanup RETURN
|
|
|
|
write_report() {
|
|
local end_time end_epoch duration i
|
|
end_time="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
end_epoch="$(date +%s)"
|
|
duration=$((end_epoch - start_epoch))
|
|
|
|
{
|
|
printf '# Logos Storage Test Report\n\n'
|
|
printf '- **Status:** PASS\n'
|
|
printf '- **Started:** `%s`\n' "$start_time"
|
|
printf '- **Finished:** `%s`\n' "$end_time"
|
|
printf '- **Duration:** `%ss`\n' "$duration"
|
|
printf '- **Target:** `%s`\n' "$target"
|
|
printf '- **Remote source:** `remote`\n'
|
|
printf '- **File sizes:** `%s`\n' "$TEST_FILE_SIZES"
|
|
printf '- **Workspace:** `%s`\n' "$workspace"
|
|
printf '- **Cleanup failures:** `%s`\n\n' "$cleanup_failures"
|
|
|
|
printf '## Files\n\n'
|
|
printf '| # | Size | Bytes | CID | SHA-256 | Source | Download |\n'
|
|
printf '|---:|---:|---:|---|---|---|---|\n'
|
|
for i in "${!result_cids[@]}"; do
|
|
printf '| %d | `%s` | `%s` | `%s` | `%s` | `%s` | `%s` |\n' \
|
|
"$((i + 1))" \
|
|
"${result_sizes[$i]}" \
|
|
"${result_bytes[$i]}" \
|
|
"${result_cids[$i]}" \
|
|
"${result_hashes[$i]}" \
|
|
"${result_sources[$i]}" \
|
|
"${result_downloads[$i]}"
|
|
done
|
|
|
|
printf '\n## Cleanup\n\n'
|
|
if [[ ${#cleanup_messages[@]} -eq 0 ]]; then
|
|
printf '- No cleanup actions recorded.\n'
|
|
else
|
|
for i in "${!cleanup_messages[@]}"; do
|
|
printf '- %s\n' "${cleanup_messages[$i]}"
|
|
done
|
|
fi
|
|
} > "$report_path"
|
|
}
|
|
|
|
printf 'Starting Logos Storage remote-to-%s test\n' "$target"
|
|
printf ' workspace: %s\n' "$workspace"
|
|
printf ' report: %s\n' "$report_path"
|
|
printf ' sizes: %s\n' "$TEST_FILE_SIZES"
|
|
|
|
local size index=0
|
|
for size in $TEST_FILE_SIZES; do
|
|
local bytes src out cid src_hash out_hash
|
|
bytes="$(size_to_bytes "$size")"
|
|
(( bytes <= max_bytes )) || die "test file size exceeds 10MB limit: $size"
|
|
|
|
index=$((index + 1))
|
|
src="${workspace}/source-${index}-${size}.bin"
|
|
out="${workspace}/download-${index}-${size}.bin"
|
|
dd if=/dev/urandom of="$src" bs="$size" count=1 status=none
|
|
src_hash="$(sha256sum "$src" | awk '{ print $1 }')"
|
|
|
|
printf '\n[%d] Generate %s random file (%s bytes)\n' "$index" "$size" "$bytes"
|
|
printf '[%d] Upload to remote\n' "$index"
|
|
cid="$(target_upload_file remote "$src")"
|
|
cids+=("$cid")
|
|
|
|
printf '[%d] Download via %s: %s\n' "$index" "$target" "$cid"
|
|
if [[ "$target" == 'local' ]]; then
|
|
target_fetch_cid local "$cid" --wait >/dev/null
|
|
local_cids+=("$cid")
|
|
target_download_cid local "$cid" "$out" >/dev/null
|
|
else
|
|
target_download_cid lib "$cid" "$out" >/dev/null
|
|
local_cids+=("$cid")
|
|
fi
|
|
|
|
out_hash="$(sha256sum "$out" | awk '{ print $1 }')"
|
|
[[ "$src_hash" == "$out_hash" ]] || die "hash mismatch for cid $cid"
|
|
result_sizes+=("$size")
|
|
result_bytes+=("$bytes")
|
|
result_sources+=("$src")
|
|
result_downloads+=("$out")
|
|
result_cids+=("$cid")
|
|
result_hashes+=("$src_hash")
|
|
printf '[%d] OK sha256=%s\n' "$index" "$src_hash"
|
|
done
|
|
|
|
printf '\nCleaning up remote and %s CIDs...\n' "$target"
|
|
cleanup
|
|
trap - RETURN
|
|
write_report
|
|
|
|
printf '\nTest passed\n'
|
|
printf ' target: %s\n' "$target"
|
|
printf ' files validated: %d\n' "$index"
|
|
printf ' cleanup failures: %d\n' "$cleanup_failures"
|
|
printf ' report: %s\n' "$report_path"
|
|
}
|
|
|
|
target_command() {
|
|
local target="$1"
|
|
local command="${2:-help}"
|
|
shift 2 || true
|
|
|
|
case "$command" in
|
|
upload) target_upload_file "$target" "${1:-}" ;;
|
|
upload-random) target_upload_random "$target" "$@" ;;
|
|
download) target_download_cid "$target" "$@" ;;
|
|
fetch) target_fetch_cid "$target" "$@" ;;
|
|
list) [[ $# -eq 0 ]] || die 'list does not accept arguments'; target_list_cids "$target" ;;
|
|
delete) target_delete_cid "$target" "$@" ;;
|
|
delete-all) target_delete_all "$target" "$@" ;;
|
|
exists) target_exists_cid "$target" "$@" ;;
|
|
space) [[ $# -eq 0 ]] || die 'space does not accept arguments'; target_simple_get "$target" 'space' ;;
|
|
peerid) [[ $# -eq 0 ]] || die 'peerid does not accept arguments'; target_simple_get "$target" 'peerid' ;;
|
|
test) [[ $# -eq 0 ]] || die 'test does not accept arguments yet'; target_test "$target" ;;
|
|
spr|debug|manifest|connect)
|
|
[[ "$target" == 'lib' ]] || die "$command is currently supported only for lib target"
|
|
lib_only_command "$command" "$@"
|
|
;;
|
|
help|--help|-h)
|
|
usage
|
|
;;
|
|
*)
|
|
die "unknown command for target '$target': $command"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
cmd="${1:-help}"
|
|
shift || true
|
|
|
|
if is_target "$cmd"; then
|
|
target_command "$cmd" "$@"
|
|
exit 0
|
|
fi
|
|
|
|
case "$cmd" in
|
|
help|--help|-h)
|
|
usage
|
|
;;
|
|
tunnel)
|
|
case "${1:-}" in
|
|
start) tunnel_start ;;
|
|
stop) tunnel_stop ;;
|
|
status)
|
|
if tunnel_status; then
|
|
printf 'tunnel running\n'
|
|
else
|
|
printf 'tunnel stopped\n'
|
|
exit 1
|
|
fi
|
|
;;
|
|
*) die 'usage: tunnel start|stop|status' ;;
|
|
esac
|
|
;;
|
|
make-file) make_file "$@" ;;
|
|
last-cid) last_cid "$@" ;;
|
|
*)
|
|
usage >&2
|
|
exit 1
|
|
;;
|
|
esac
|