tests: write salvage payloads through NCP
This commit is contained in:
@@ -21,7 +21,7 @@ static void usage(const char *prog)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s [--expect-delete CODE] [--create-only] [--delete-only] "
|
||||
"[ncpfs options] PATH\n"
|
||||
"[--payload TEXT] [ncpfs options] PATH\n"
|
||||
"\n"
|
||||
"ncpfs options are parsed by ncp_initialize(), for example:\n"
|
||||
" -S SERVER -U USER -P PASSWORD -n\n"
|
||||
@@ -54,6 +54,7 @@ int main(int argc, char **argv)
|
||||
struct ncp_file_info file_info;
|
||||
int create = 1;
|
||||
int delete = 1;
|
||||
const char *payload = NULL;
|
||||
int i;
|
||||
long err;
|
||||
|
||||
@@ -83,6 +84,13 @@ int main(int argc, char **argv)
|
||||
} else if (!strcmp(argv[i], "--delete-only")) {
|
||||
create = 0;
|
||||
delete = 1;
|
||||
} else if (!strcmp(argv[i], "--payload")) {
|
||||
if (++i >= argc) {
|
||||
fprintf(stderr, "missing --payload value\n");
|
||||
ncp_close(conn);
|
||||
return 2;
|
||||
}
|
||||
payload = argv[i];
|
||||
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
|
||||
usage(argv[0]);
|
||||
ncp_close(conn);
|
||||
@@ -112,6 +120,23 @@ int main(int argc, char **argv)
|
||||
ncp_close(conn);
|
||||
return 1;
|
||||
}
|
||||
if (payload) {
|
||||
size_t payload_len = strlen(payload);
|
||||
err = ncp_write(conn, file_info.file_id, 0, payload_len, payload);
|
||||
if (!err)
|
||||
err = ncp_write(conn, file_info.file_id, payload_len, 1, "\n");
|
||||
if (err) {
|
||||
fprintf(stderr,
|
||||
"NCP write failed: path=%s error=0x%04x\n",
|
||||
path, (unsigned int)err);
|
||||
ncp_close_file(conn, file_info.file_id);
|
||||
ncp_close(conn);
|
||||
return 1;
|
||||
}
|
||||
printf("NCP write path=%s bytes=%lu verified\n",
|
||||
path, (unsigned long)(payload_len + 1));
|
||||
}
|
||||
|
||||
err = ncp_close_file(conn, file_info.file_id);
|
||||
if (err) {
|
||||
fprintf(stderr,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
# End-to-end mars_nwe salvage smoke suite.
|
||||
#
|
||||
# The suite purges stale salvage entries through NCP first, then runs two
|
||||
# create/write/delete/recover cycles. Each cycle cats the .recycle payload
|
||||
# after delete and the restored live file after recover so content changes are
|
||||
# visible in the report.
|
||||
# The suite purges stale salvage entries through NCP first, then creates up to
|
||||
# three deleted versions through NCP writes/deletes. It cats the live payload,
|
||||
# the .recycle payload for each version, and the restored live file after
|
||||
# recover so content changes are visible in the report.
|
||||
|
||||
set -u
|
||||
|
||||
@@ -23,6 +23,7 @@ DELETED_BY=""
|
||||
OUT_FILE=""
|
||||
KEEP_GOING=1
|
||||
CLEAN_ARTIFACTS=1
|
||||
CYCLE_COUNT=3
|
||||
|
||||
usage() {
|
||||
cat <<USAGE
|
||||
@@ -36,17 +37,17 @@ Options:
|
||||
--recycle-name NAME Recycle repository name (default: $RECYCLE_REPOSITORY)
|
||||
--salvage-name NAME Salvage metadata repository name (default: $SALVAGE_REPOSITORY)
|
||||
--out FILE Write the complete report to FILE as well as stdout
|
||||
--no-clean-artifacts Do not try to remove stale test artifacts first
|
||||
--cycles N Number of NCP write/delete versions to create, 1..3 (default: 3)
|
||||
--no-clean-artifacts Accepted for compatibility; cleanup is done through NCP purge
|
||||
--stop-on-failure Stop after the first failing check
|
||||
-h, --help Show this help
|
||||
|
||||
The suite uses tests/salvage/ncp_delete_smoke to create and delete the file
|
||||
through classic NCP requests, and tests/salvage/ncp_salvage_purge_smoke to purge
|
||||
stale salvage entries through NCP before the content checks start. It never
|
||||
removes the live file through local Unix unlink/rm; local filesystem access is
|
||||
used to write/cat the live test payload and to inspect .recycle/.salvage.
|
||||
Cleanup failures are warnings because the server may have created those files as
|
||||
another Unix user.
|
||||
The suite uses tests/salvage/ncp_delete_smoke to create, write and delete the
|
||||
file through classic NCP requests, and tests/salvage/ncp_salvage_purge_smoke to
|
||||
purge stale salvage entries through NCP before the content checks start. It does
|
||||
not use local Unix rm/unlink/write for cleanup or payload changes; local
|
||||
filesystem access is only used for cat/readback of live, .recycle and .salvage
|
||||
files.
|
||||
USAGE
|
||||
}
|
||||
|
||||
@@ -62,6 +63,7 @@ while [ $# -gt 0 ]; do
|
||||
--recycle-name) RECYCLE_REPOSITORY=$2; shift 2 ;;
|
||||
--salvage-name) SALVAGE_REPOSITORY=$2; shift 2 ;;
|
||||
--out) OUT_FILE=$2; shift 2 ;;
|
||||
--cycles) CYCLE_COUNT=$2; shift 2 ;;
|
||||
--no-clean-artifacts) CLEAN_ARTIFACTS=0; shift ;;
|
||||
--stop-on-failure) KEEP_GOING=0; shift ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
@@ -80,6 +82,10 @@ if [ "$PATH_SET" -ne "$UNIX_PATH_SET" ]; then
|
||||
echo "--path and --unix-path should be supplied together so both point to the same file" >&2
|
||||
exit 2
|
||||
fi
|
||||
case "$CYCLE_COUNT" in
|
||||
1|2|3) ;;
|
||||
*) echo "--cycles must be 1, 2 or 3" >&2; exit 2 ;;
|
||||
esac
|
||||
|
||||
REPORT_TMP=$(mktemp "${TMPDIR:-/tmp}/mars-salvage-suite.XXXXXX")
|
||||
FAILURES=0
|
||||
@@ -188,43 +194,31 @@ prepare_paths() {
|
||||
DIRNAME=$(dirname -- "$RELATIVE_PATH")
|
||||
[ "$DIRNAME" = "." ] && DIRNAME=""
|
||||
COPY_NAME="Copy #1 of $BASENAME"
|
||||
COPY2_NAME="Copy #2 of $BASENAME"
|
||||
SCAN_PATH=$(netware_directory_path "$NETWARE_PATH") || return 1
|
||||
|
||||
if [ -n "$DIRNAME" ]; then
|
||||
FIRST_REL="$DELETED_BY/$DIRNAME/$BASENAME"
|
||||
SECOND_REL="$DELETED_BY/$DIRNAME/$COPY_NAME"
|
||||
THIRD_REL="$DELETED_BY/$DIRNAME/$COPY2_NAME"
|
||||
else
|
||||
FIRST_REL="$DELETED_BY/$BASENAME"
|
||||
SECOND_REL="$DELETED_BY/$COPY_NAME"
|
||||
THIRD_REL="$DELETED_BY/$COPY2_NAME"
|
||||
fi
|
||||
|
||||
FIRST_RECYCLE=$(resolve_case_path "$VOLUME_ROOT" "$RECYCLE_REPOSITORY/$FIRST_REL")
|
||||
SECOND_RECYCLE=$(resolve_case_path "$VOLUME_ROOT" "$RECYCLE_REPOSITORY/$SECOND_REL")
|
||||
THIRD_RECYCLE=$(resolve_case_path "$VOLUME_ROOT" "$RECYCLE_REPOSITORY/$THIRD_REL")
|
||||
FIRST_META=$(resolve_case_path "$VOLUME_ROOT" "$SALVAGE_REPOSITORY/$FIRST_REL.json")
|
||||
SECOND_META=$(resolve_case_path "$VOLUME_ROOT" "$SALVAGE_REPOSITORY/$SECOND_REL.json")
|
||||
}
|
||||
|
||||
clean_artifact() {
|
||||
local artifact=$1
|
||||
if [ -e "$artifact" ]; then
|
||||
emit "rm '$artifact'"
|
||||
if rm -f -- "$artifact" 2>>"$REPORT_TMP"; then
|
||||
:
|
||||
else
|
||||
emit "warning: could not remove stale test artifact: $artifact"
|
||||
fi
|
||||
else
|
||||
emit "clean: $artifact"
|
||||
fi
|
||||
THIRD_META=$(resolve_case_path "$VOLUME_ROOT" "$SALVAGE_REPOSITORY/$THIRD_REL.json")
|
||||
}
|
||||
|
||||
clean_stale_artifacts() {
|
||||
[ "$CLEAN_ARTIFACTS" -eq 1 ] || return 0
|
||||
section "pre-clean stale salvage artifacts"
|
||||
clean_artifact "$FIRST_META"
|
||||
clean_artifact "$SECOND_META"
|
||||
clean_artifact "$FIRST_RECYCLE"
|
||||
clean_artifact "$SECOND_RECYCLE"
|
||||
emit "local rm cleanup skipped; stale salvage entries are purged through NCP 87/18"
|
||||
}
|
||||
|
||||
check_file() {
|
||||
@@ -272,30 +266,21 @@ cat_text_file() {
|
||||
return 0
|
||||
}
|
||||
|
||||
write_live_payload() {
|
||||
local label=$1 content=$2
|
||||
run_ncp_create_with_payload() {
|
||||
local label=$1 content=$2 status
|
||||
section "$label"
|
||||
emit "path=$UNIX_PATH"
|
||||
emit "content=$content"
|
||||
printf '%s\n' "$content" >"$UNIX_PATH" 2>>"$REPORT_TMP" || {
|
||||
fail_check "could not write live payload: $UNIX_PATH"
|
||||
return 1
|
||||
}
|
||||
cat_text_file "$label: live file after write" "$UNIX_PATH" "$content"
|
||||
}
|
||||
|
||||
run_ncp_create_only() {
|
||||
local label=$1 status
|
||||
section "$label"
|
||||
emit "\$ ./ncp_delete_smoke --create-only -S '$SERVER' -U '$USER_NAME' -P ****** '$NETWARE_PATH'"
|
||||
"$SCRIPT_DIR/ncp_delete_smoke" --create-only -S "$SERVER" -U "$USER_NAME" \
|
||||
-P "$PASSWORD" "$NETWARE_PATH" 2>&1 | tee -a "$REPORT_TMP"
|
||||
emit "payload=$content"
|
||||
emit "\$ ./ncp_delete_smoke --create-only --payload '$content' -S '$SERVER' -U '$USER_NAME' -P ****** '$NETWARE_PATH'"
|
||||
"$SCRIPT_DIR/ncp_delete_smoke" --create-only --payload "$content" \
|
||||
-S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$NETWARE_PATH" \
|
||||
2>&1 | tee -a "$REPORT_TMP"
|
||||
status=${PIPESTATUS[0]}
|
||||
emit "[exit=$status]"
|
||||
if [ "$status" -ne 0 ]; then
|
||||
fail_check "NCP create-only failed for $NETWARE_PATH"
|
||||
fail_check "NCP create/write failed for $NETWARE_PATH"
|
||||
return 1
|
||||
fi
|
||||
cat_text_file "$label: cat live file after NCP write" "$UNIX_PATH" "$content"
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -329,6 +314,13 @@ count_salvage_entries() {
|
||||
status=${PIPESTATUS[0]}
|
||||
emit "[exit=$status]"
|
||||
if [ "$status" -ne 0 ]; then
|
||||
if grep -q "found no entries" "$scan_tmp" && grep -q "last_error=0x89ff" "$scan_tmp"; then
|
||||
basename_count=0
|
||||
emit "NCP salvage scan matched 0 entries named $BASENAME"
|
||||
printf -v "$out_var" '%s' "$basename_count"
|
||||
rm -f "$scan_tmp"
|
||||
return 0
|
||||
fi
|
||||
fail_check "NCP salvage scan failed for $SCAN_PATH"
|
||||
rm -f "$scan_tmp"
|
||||
return 1
|
||||
@@ -364,8 +356,20 @@ run_ncp_salvage_purge_all() {
|
||||
return 0
|
||||
}
|
||||
|
||||
salvage_paths_for_index() {
|
||||
local index=$1 recycle_var=$2 meta_var=$3 recycle_path meta_path
|
||||
case "$index" in
|
||||
0) recycle_path=$FIRST_RECYCLE; meta_path=$FIRST_META ;;
|
||||
1) recycle_path=$SECOND_RECYCLE; meta_path=$SECOND_META ;;
|
||||
2) recycle_path=$THIRD_RECYCLE; meta_path=$THIRD_META ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
printf -v "$recycle_var" '%s' "$recycle_path"
|
||||
printf -v "$meta_var" '%s' "$meta_path"
|
||||
}
|
||||
|
||||
recover_first_salvage_entry() {
|
||||
local label=$1 expected_content=$2 before_count=0 after_count=0 status
|
||||
local label=$1 before_count=0 after_count=0 status
|
||||
|
||||
count_salvage_entries "$label: NCP salvage scan before recover" before_count || return 1
|
||||
if [ "$before_count" -lt 1 ]; then
|
||||
@@ -387,7 +391,9 @@ recover_first_salvage_entry() {
|
||||
fi
|
||||
|
||||
check_file "$label: restored live payload exists" "$UNIX_PATH" && \
|
||||
cat_text_file "$label: cat restored live file" "$UNIX_PATH" "$expected_content"
|
||||
cat_text_file "$label: cat restored live file" "$UNIX_PATH"
|
||||
grep -q "mars_nwe salvage payload cycle" "$UNIX_PATH" || \
|
||||
fail_check "$label: restored live file does not contain expected salvage payload marker"
|
||||
|
||||
count_salvage_entries "$label: NCP salvage scan after recover" after_count || return 1
|
||||
if [ "$after_count" -ne $((before_count - 1)) ]; then
|
||||
@@ -397,29 +403,38 @@ recover_first_salvage_entry() {
|
||||
return 0
|
||||
}
|
||||
|
||||
run_recover_cycle() {
|
||||
local label=$1 content=$2
|
||||
run_delete_capture_cycle() {
|
||||
local index=$1 label=$2 content=$3 recycle_path meta_path
|
||||
|
||||
run_ncp_create_only "$label: NCP create live file" || return 1
|
||||
write_live_payload "$label: modify live file through Linux" "$content" || return 1
|
||||
salvage_paths_for_index "$index" recycle_path meta_path || {
|
||||
fail_check "$label: unsupported version index $index"
|
||||
return 1
|
||||
}
|
||||
|
||||
run_ncp_create_with_payload "$label: NCP create/write live file" "$content" || return 1
|
||||
run_ncp_delete_only "$label: NCP delete live file" || return 1
|
||||
|
||||
check_file "$label: recycle payload before recover" "$FIRST_RECYCLE" && \
|
||||
cat_text_file "$label: cat recycle payload before recover" "$FIRST_RECYCLE" "$content"
|
||||
check_file "$label: salvage metadata before recover" "$FIRST_META" && \
|
||||
cat_metadata "$label: cat salvage metadata before recover" "$FIRST_META"
|
||||
check_file "$label: recycle payload before recover" "$recycle_path" && \
|
||||
cat_text_file "$label: cat recycle payload before recover" "$recycle_path" "$content"
|
||||
check_file "$label: salvage metadata before recover" "$meta_path" && \
|
||||
cat_metadata "$label: cat salvage metadata before recover" "$meta_path"
|
||||
}
|
||||
|
||||
recover_first_salvage_entry "$label" "$content" || return 1
|
||||
run_version_capture_cycles() {
|
||||
local i label content count salvage_count=0
|
||||
i=0
|
||||
while [ "$i" -lt "$CYCLE_COUNT" ]; do
|
||||
count=$((i + 1))
|
||||
label="version capture #$count"
|
||||
content="mars_nwe salvage payload cycle $count"
|
||||
run_delete_capture_cycle "$i" "$label" "$content" || return 1
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
if [ -e "$FIRST_RECYCLE" ]; then
|
||||
fail_check "$label: recycle payload still exists after recover: $FIRST_RECYCLE"
|
||||
else
|
||||
emit "$label: recycle payload consumed: $FIRST_RECYCLE"
|
||||
fi
|
||||
if [ -e "$FIRST_META" ]; then
|
||||
fail_check "$label: metadata sidecar still exists after recover: $FIRST_META"
|
||||
else
|
||||
emit "$label: metadata sidecar consumed: $FIRST_META"
|
||||
count_salvage_entries "NCP salvage scan after version captures" salvage_count || return 1
|
||||
if [ "$salvage_count" -ne "$CYCLE_COUNT" ]; then
|
||||
fail_check "expected $CYCLE_COUNT salvage entries after version captures, got $salvage_count"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -441,14 +456,17 @@ emit "deleted_by=$DELETED_BY"
|
||||
emit "recycle_repository=$RECYCLE_REPOSITORY"
|
||||
emit "salvage_repository=$SALVAGE_REPOSITORY"
|
||||
emit "clean_artifacts=$CLEAN_ARTIFACTS"
|
||||
emit "cycles=$CYCLE_COUNT"
|
||||
|
||||
if prepare_paths; then
|
||||
emit "volume_root=$VOLUME_ROOT"
|
||||
emit "relative_path=$RELATIVE_PATH"
|
||||
emit "first_recycle=$FIRST_RECYCLE"
|
||||
emit "second_recycle=$SECOND_RECYCLE"
|
||||
emit "third_recycle=$THIRD_RECYCLE"
|
||||
emit "first_metadata=$FIRST_META"
|
||||
emit "second_metadata=$SECOND_META"
|
||||
emit "third_metadata=$THIRD_META"
|
||||
emit "scan_path=$SCAN_PATH"
|
||||
clean_stale_artifacts
|
||||
else
|
||||
@@ -460,8 +478,8 @@ fi
|
||||
cleanup_live_file_if_present
|
||||
run_ncp_salvage_purge_all
|
||||
|
||||
run_recover_cycle "recover cycle #1" "mars_nwe salvage payload cycle 1"
|
||||
run_recover_cycle "recover cycle #2" "mars_nwe salvage payload cycle 2 after recover"
|
||||
run_version_capture_cycles
|
||||
recover_first_salvage_entry "recover first version after $CYCLE_COUNT captures"
|
||||
|
||||
finish_report
|
||||
[ "$FAILURES" -eq 0 ]
|
||||
|
||||
Reference in New Issue
Block a user