do not edit — generated by btf.
git.druid.rocksindexdruid520mptest/suites/commands.sh

test/suites/commands.sh


# suite: frontend command correctness for slotted/stray packages --
# file-conflict rollback safety, and fetch/files/revdep/reinstall/clean's
# handling of a bare name for a statically slotted or stray package.
 
# file-conflict rollback must never delete another package's file: a
# rejected install may leave content overwritten (its OWN install phase
# ran before conflict detection), but never DELETE the file, and a
# subsequent reinstall of the original owner must recover it.
test_file_conflict_no_data_loss() {
	t_begin "file_conflict_no_data_loss"
	reset_state
	mkport rt12A <<'EOF'
pkg_name="rt12A"
pkg_ver="1.0"
install:
	mkdir -p $MP_PREFIX/share/rt12collide
	echo A > $MP_PREFIX/share/rt12collide/same.txt
	touch $MP_PREFIX/rt12A-own-marker
remove:
	rm -rf $MP_PREFIX/share/rt12collide
	rm -f $MP_PREFIX/rt12A-own-marker
EOF
	mkport rt12B <<'EOF'
pkg_name="rt12B"
pkg_ver="1.0"
install:
	mkdir -p $MP_PREFIX/share/rt12collide
	echo B > $MP_PREFIX/share/rt12collide/same.txt
remove:
	rm -rf $MP_PREFIX/share/rt12collide
EOF
	mp install rt12A >/tmp/rt12.out 2>&1
	mp install rt12B >>/tmp/rt12.out 2>&1
	assert_file_exists "$MP_PREFIX/share/rt12collide/same.txt" "$CUR_TEST" || return
	assert_file_exists "$MP_PREFIX/rt12A-own-marker" "$CUR_TEST" || return
	mp reinstall rt12A >>/tmp/rt12.out 2>&1
	content=$(cat "$MP_PREFIX/share/rt12collide/same.txt" 2>/dev/null)
	assert_contains "$content" "A" "$CUR_TEST" || return
	t_pass
}
 
# fetch.pl / files.pl / revdep.pl / reinstall_pkg: a bare name for a
# statically slotted package (two directories, one pkg_name) must not be
# silently mishandled -- fetch cache is per-slot, files/revdep resolve
# via the one installed slot, and reinstall checks HOLD_VERSION before
# removing the old copy.
test_slotted_barename_commands() {
	t_begin "slotted_barename_commands"
	reset_state
	mkport rt13-12 <<'EOF'
pkg_name="rt13stub"
pkg_ver="12.0"
pkg_slot="12"
pkg_pref="10"
fetch:
	mkdir -p rt13stub
install:
	touch $MP_PREFIX/rt13stub12-installed
remove:
	rm -f $MP_PREFIX/rt13stub12-installed
EOF
	mkport rt13-13 <<'EOF'
pkg_name="rt13stub"
pkg_ver="13.0"
pkg_slot="13"
pkg_pref="20"
fetch:
	mkdir -p rt13stub
install:
	touch $MP_PREFIX/rt13stub13-installed
remove:
	rm -f $MP_PREFIX/rt13stub13-installed
EOF
	mkport rt13consumer <<'EOF'
pkg_name="rt13consumer"
pkg_ver="1.0"
pkg_deps="rt13stub:12"
install:
	touch $MP_PREFIX/rt13consumer-installed
remove:
	rm -f $MP_PREFIX/rt13consumer-installed
EOF
	mp fetch 'rt13stub:12' >/tmp/rt13.out 2>&1
	out=$(mp fetch 'rt13stub:13' 2>&1)
	assert_not_contains "$out" "already has a cached fetch" "$CUR_TEST" || return
	rm -rf "$WD/fetch-cache"
 
	mp install 'rt13stub:12' >>/tmp/rt13.out 2>&1
	mp install rt13consumer >>/tmp/rt13.out 2>&1
	files_out=$(mp files rt13stub 2>&1)
	assert_contains "$files_out" "rt13stub12-installed" "$CUR_TEST" || return
	revdep_out=$(mp revdep rt13stub 2>&1)
	assert_contains "$revdep_out" "rt13consumer" "$CUR_TEST" || return
 
	mp remove --force rt13consumer >>/tmp/rt13.out 2>&1
	cat >> "$CONF" <<'EOF'
rt13stub:12:
	HOLD_VERSION=999.0
EOF
	out2=$(mp reinstall rt13stub 2>&1)
	assert_contains "$out2" "does not match HOLD_VERSION" "$CUR_TEST" || return
	assert_file_exists "$MP_PREFIX/rt13stub-12/rt13stub12-installed" "$CUR_TEST" || return
	t_pass
}
 
# mp clean must resolve a bare name to a stray/stuck slotted stage dir
# that has NO corresponding db entry at all -- resolved_db_key can't
# help here, since there's nothing in the db to resolve from; this
# needs its own directory-listing fallback scan.
test_clean_slotted_stray_stagedir() {
	t_begin "clean_slotted_stray_stagedir"
	reset_state
	mkdir -p "$WD/rt19stray:12"
	mp clean rt19stray >/tmp/rt19.out 2>&1
	assert_file_absent "$WD/rt19stray:12" "$CUR_TEST" || return
	t_pass
}
 
# the mpx backend's own snapshot/stage/unstage primitives: snapshot
# emits "path\tsec.nsec" lines, stage recursively copies a nested tree
# (file contents intact), unstage removes it again.
test_backend_stage_snapshot() {
	t_begin "backend_stage_snapshot"
	reset_state
	mkdir -p "$MP_PREFIX/sub" /tmp/rt36-src/nested
	echo payload > "$MP_PREFIX/sub/f.txt"
	echo inner > /tmp/rt36-src/nested/g.txt
	"$MP_BACKEND" snapshot "$MP_PREFIX" /tmp/rt36-snap.txt >/tmp/rt36.out 2>&1
	rc=$?
	assert_exit0 "$rc" "$CUR_TEST" || return
	snap=$(cat /tmp/rt36-snap.txt)
	assert_contains "$snap" "sub/f.txt" "$CUR_TEST" || return
	assert_contains "$snap" "	" "$CUR_TEST" || return
	"$MP_BACKEND" stage /tmp/rt36-src /tmp/rt36-dst >/tmp/rt36.out 2>&1
	assert_file_exists /tmp/rt36-dst/nested/g.txt "$CUR_TEST" || return
	content=$(cat /tmp/rt36-dst/nested/g.txt)
	assert_contains "$content" "inner" "$CUR_TEST" || return
	"$MP_BACKEND" unstage /tmp/rt36-dst >/tmp/rt36.out 2>&1
	assert_file_absent /tmp/rt36-dst "$CUR_TEST" || return
	rm -rf /tmp/rt36-src /tmp/rt36-dst /tmp/rt36-snap.txt
	t_pass
}
 
# the sugar commands' persistence matrix: each hold/mask/use toggle is
# recorded in pkgconf.conf and honored by the very next invocation.
sugar_case() {
	# $1 name, $2 sugar command, $3 expected pkgconf.conf substring
	t_begin "$1"
	reset_state
	printf 'GLOBAL_DEPS=" "\n' >> "$CONF"
	mkport "${1}p" <<EOF
pkg_name="${1}p"
pkg_ver="1.0"
install:
	touch \$MP_PREFIX/${1}p-installed
remove:
	rm -f \$MP_PREFIX/${1}p-installed
EOF
	mp "$2" "${1}p" >/tmp/"$1".out 2>&1
	pkgconf=$(cat "$WD/pkgconf.conf")
	assert_contains "$pkgconf" "$3" "$CUR_TEST" || return
	t_pass
}
 
run_sugar_matrix() {
	sugar_case sg_hold 'hold' 'HOLD="yes"'
	sugar_case sg_mask 'mask' 'MASK="yes"'
	sugar_case sg_unhold_after_hold 'hold' 'HOLD="yes"'
}
 
# hold then unhold round-trip clears the entry entirely; unmask after
# mask likewise.
test_sugar_clear_roundtrip() {
	t_begin "sugar_clear_roundtrip"
	reset_state
	printf 'GLOBAL_DEPS=" "\n' >> "$CONF"
	mkport rt52p <<'EOF'
pkg_name="rt52p"
pkg_ver="1.0"
install:
	touch $MP_PREFIX/rt52p-installed
remove:
	rm -f $MP_PREFIX/rt52p-installed
EOF
	mp hold rt52p >/tmp/rt52.out 2>&1
	mp unhold rt52p >>/tmp/rt52.out 2>&1
	mp mask rt52p >>/tmp/rt52.out 2>&1
	mp unmask rt52p >>/tmp/rt52.out 2>&1
	pkgconf=$(cat "$WD/pkgconf.conf")
	assert_not_contains "$pkgconf" "HOLD" "$CUR_TEST" || return
	assert_not_contains "$pkgconf" "MASK" "$CUR_TEST" || return
	t_pass
}
 
# mp files on an installed package lists every tracked file with the
# real prefix; on a never-installed one it reports no manifest.
test_files_tracked_and_missing() {
	t_begin "files_tracked_and_missing"
	reset_state
	printf 'GLOBAL_DEPS=" "\n' >> "$CONF"
	mkport rt53p <<'EOF'
pkg_name="rt53p"
pkg_ver="1.0"
install:
	mkdir -p $MP_PREFIX/share/rt53
	touch $MP_PREFIX/share/rt53/data.txt
	touch $MP_PREFIX/rt53p-installed
remove:
	rm -rf $MP_PREFIX/share/rt53
	rm -f $MP_PREFIX/rt53p-installed
EOF
	mp install rt53p >/tmp/rt53.out 2>&1
	files=$(mp files rt53p 2>&1)
	assert_contains "$files" "$MP_PREFIX/share/rt53/data.txt" "$CUR_TEST" || return
	assert_contains "$files" "$MP_PREFIX/rt53p-installed" "$CUR_TEST" || return
	out=$(mp files rt53neverinstalled 2>&1)
	assert_contains "$out" "no manifest" "$CUR_TEST" || return
	t_pass
}
 
# mp fetch on a port with no fetch phase reports the no-op; on one with
# a fetch phase, the cache dir is created and re-fetch collides loudly.
test_fetch_cache_semantics() {
	t_begin "fetch_cache_semantics"
	reset_state
	printf 'GLOBAL_DEPS=" "\n' >> "$CONF"
	mkport rt54nofetch <<'EOF'
pkg_name="rt54nofetch"
pkg_ver="1.0"
install:
	touch $MP_PREFIX/rt54nofetch-installed
remove:
	rm -f $MP_PREFIX/rt54nofetch-installed
EOF
	mkport rt54fetch <<'EOF'
pkg_name="rt54fetch"
pkg_ver="1.0"
fetch:
	mkdir -p rt54fetch
install:
	touch $MP_PREFIX/rt54fetch-installed
remove:
	rm -f $MP_PREFIX/rt54fetch-installed
EOF
	out=$(mp fetch rt54nofetch 2>&1)
	assert_contains "$out" "no separate fetch phase" "$CUR_TEST" || return
	mp fetch rt54fetch >/tmp/rt54.out 2>&1
	assert_file_exists "$WD/fetch-cache/rt54fetch" "$CUR_TEST" || return
	out=$(mp fetch rt54fetch 2>&1)
	assert_contains "$out" "already has a cached fetch" "$CUR_TEST" || return
	t_pass
}
 
# mp why on a bare name for a slotted installed package resolves to the
# installed canon and names the dependent.
test_why_bare_slotted_target() {
	t_begin "why_bare_slotted_target"
	reset_state
	printf 'GLOBAL_DEPS=" "\n' >> "$CONF"
	mkport rt55prov <<'EOF'
pkg_name="rt55prov"
pkg_ver="1.0"
pkg_slot="s55"
install:
	touch $MP_PREFIX/rt55prov-installed
remove:
	rm -f $MP_PREFIX/rt55prov-installed
EOF
	mkport rt55cons <<'EOF'
pkg_name="rt55cons"
pkg_ver="1.0"
pkg_deps="rt55prov:s55"
install:
	touch $MP_PREFIX/rt55cons-installed
remove:
	rm -f $MP_PREFIX/rt55cons-installed
EOF
	mp install rt55cons >/tmp/rt55.out 2>&1
	why=$(mp why rt55prov 2>&1)
	assert_contains "$why" "rt55cons" "$CUR_TEST" || return
	t_pass
}
 
# mp list --installed dumps db format name<TAB>ver<TAB>license<TAB>
# requested, one line per canon.
test_list_installed_format() {
	t_begin "list_installed_format"
	reset_state
	printf 'GLOBAL_DEPS=" "\n' >> "$CONF"
	mkport rt56p <<'EOF'
pkg_name="rt56p"
pkg_ver="2.5"
pkg_license="BSD"
install:
	touch $MP_PREFIX/rt56p-installed
remove:
	rm -f $MP_PREFIX/rt56p-installed
EOF
	mp install rt56p >/tmp/rt56.out 2>&1
	list=$(mp list --installed 2>&1)
	assert_contains "$list" "rt56p	2.5	BSD	1" "$CUR_TEST" || return
	t_pass
}
 
 
# end-to-end (not just mplib::portformat's own unit-level matrix, see
# portformat.sh's enuse_default_* cases): a "+flag" default-enabled USE
# flag actually reaches an install phase script as a real USE_<flag>=1
# env var with NOTHING configured at all, "mp use pkg -flag" then
# genuinely turns it off on a REAL reinstall (not just what the toggle
# command itself reports), and the port's declared-off flag never turns
# on by itself.
test_use_flag_default_toggle() {
	t_begin "use_flag_default_toggle"
	reset_state
	printf 'GLOBAL_DEPS=" "\n' >> "$CONF"
	mkport rt57p <<'EOF'
pkg_name="rt57p"
pkg_ver="1.0"
pkg_use="+alwayson offbydefault"
install:
	echo "alwayson=[$USE_alwayson] offbydefault=[$USE_offbydefault]" > $MP_PREFIX/rt57-log
	touch $MP_PREFIX/rt57p-installed
remove:
	rm -f $MP_PREFIX/rt57p-installed $MP_PREFIX/rt57-log
EOF
	mp install rt57p >/tmp/rt57.out 2>&1
	log1=$(cat "$MP_PREFIX/rt57-log" 2>/dev/null)
	mp use rt57p -alwayson >>/tmp/rt57.out 2>&1
	mp remove --force rt57p >>/tmp/rt57.out 2>&1
	mp install rt57p >>/tmp/rt57.out 2>&1
	log2=$(cat "$MP_PREFIX/rt57-log" 2>/dev/null)
	assert_contains "$log1" "alwayson=[1] offbydefault=[]" "$CUR_TEST" || return
	assert_contains "$log2" "alwayson=[] offbydefault=[]" "$CUR_TEST" || return
	t_pass
}
 
# "mpx version" reports the exact cc/cflags THIS build actually used
# (buildinfo.h, regenerated by mk/b.sh every build -- never hand-
# maintained), and "mp version"/"mp --version" (identical) layer mp's
# own version, that same mpx report, and the full command/plugin list
# on top -- the same discover_cmds()/plugin_names() usage() itself uses.
test_version_reports_build_and_commands() {
	t_begin "version_reports_build_and_commands"
	reset_state
	out=$("$MP_BACKEND" version 2>&1)
	rc=$?
	assert_exit0 "$rc" "$CUR_TEST" || return
	assert_contains "$out" "cc=" "$CUR_TEST (mpx cc=)" || return
	assert_contains "$out" "-std=c89" "$CUR_TEST (mpx cflags)" || return
 
	out=$(mp version 2>&1)
	rc=$?
	assert_exit0 "$rc" "$CUR_TEST" || return
	assert_contains "$out" "mp " "$CUR_TEST (mp's own version)" || return
	assert_contains "$out" "cc=" "$CUR_TEST (mp version includes mpx build info)" || return
	assert_contains "$out" "commands:" "$CUR_TEST" || return
	assert_contains "$out" "install" "$CUR_TEST (a real core command listed)" || return
	assert_contains "$out" "plugins:" "$CUR_TEST" || return
	assert_contains "$out" "lint" "$CUR_TEST (a real plugin listed)" || return
 
	dashout=$(mp --version 2>&1)
	assert_contains "$dashout" "commands:" "$CUR_TEST (--version alias)" || return
	t_pass
}
 
run_commands_suite() {
	test_file_conflict_no_data_loss
	test_slotted_barename_commands
	test_clean_slotted_stray_stagedir
	test_backend_stage_snapshot
	run_sugar_matrix
	test_sugar_clear_roundtrip
	test_files_tracked_and_missing
	test_fetch_cache_semantics
	test_why_bare_slotted_target
	test_list_installed_format
	test_use_flag_default_toggle
	test_version_reports_build_and_commands
}
powered by btf.