Skip to content
Open
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
38 changes: 24 additions & 14 deletions scripts/macos-tcfs-rollout-readiness.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Options:
(default: ~/Library/LaunchAgents/dev.tinyland.tcfsd.plist)
--launch-label <label> launchd label (default: dev.tinyland.tcfsd)
--app-path <path> TCFSProvider.app path
(default: ~/Applications/TCFSProvider.app)
(default: /Applications/TCFSProvider.app)
--plugin-id <id> FileProvider extension id
(default: io.tinyland.tcfs.fileprovider)
--status-timeout <seconds> Bound tcfs status (default: 8)
Expand All @@ -38,7 +38,7 @@ EXPECTED_TUMMYCRYPT_REV="${TCFS_EXPECTED_TUMMYCRYPT_REV:-}"
LAB_ROOT="${TCFS_LAB_ROOT:-$HOME/git/lab}"
LAUNCH_AGENT="${TCFS_LAUNCH_AGENT:-$HOME/Library/LaunchAgents/dev.tinyland.tcfsd.plist}"
LAUNCH_LABEL="${TCFS_LAUNCH_LABEL:-dev.tinyland.tcfsd}"
APP_PATH="${TCFS_APP_PATH:-$HOME/Applications/TCFSProvider.app}"
APP_PATH="${TCFS_APP_PATH:-/Applications/TCFSProvider.app}"
PLUGIN_ID="${TCFS_PLUGIN_ID:-io.tinyland.tcfs.fileprovider}"
STATUS_TIMEOUT="${TCFS_STATUS_TIMEOUT:-8}"
SKIP_STATUS="${TCFS_SKIP_STATUS:-0}"
Expand Down Expand Up @@ -210,8 +210,7 @@ plist_value() {
}

check_launch_agent() {
local program=""
local status=""
local argv0=""

if [[ ! -f "$LAUNCH_AGENT" ]]; then
fail "LaunchAgent plist not found: $LAUNCH_AGENT"
Expand All @@ -222,23 +221,23 @@ check_launch_agent() {
note "launch label: $LAUNCH_LABEL"

if [[ -x "$PLISTBUDDY_BIN" ]]; then
program="$(plist_value "ProgramArguments:2" "$LAUNCH_AGENT" || true)"
if [[ -n "$program" ]]; then
note "launch agent command: $program"
note "launch agent command inspection: not executed"
argv0="$(plist_value "ProgramArguments:0" "$LAUNCH_AGENT" || true)"
if [[ -n "$argv0" ]]; then
note "launch agent command: configured (argv0: $argv0)"
note "launch agent command inspection: redacted"
else
warn "could not read ProgramArguments:2 from LaunchAgent"
warn "could not read ProgramArguments:0 from LaunchAgent"
fi
else
warn "PlistBuddy not executable: $PLISTBUDDY_BIN"
fi

if command -v "$LAUNCHCTL_BIN" >/dev/null 2>&1; then
status="$("$LAUNCHCTL_BIN" print "gui/$(id -u)/$LAUNCH_LABEL" 2>&1 || true)"
if grep -Fq "Could not find service" <<<"$status"; then
fail "launchd service not found: $LAUNCH_LABEL"
else
if "$LAUNCHCTL_BIN" list 2>/dev/null \
| awk -v label="$LAUNCH_LABEL" '$3 == label { found = 1 } END { exit found ? 0 : 1 }'; then
note "launchd service: present ($LAUNCH_LABEL)"
else
fail "launchd service not found: $LAUNCH_LABEL"
fi
else
warn "launchctl not found"
Expand Down Expand Up @@ -280,21 +279,32 @@ check_app_bundle() {
check_pluginkit() {
local output
local count
local expected_extension

if ! command -v "$PLUGINKIT_BIN" >/dev/null 2>&1; then
warn "pluginkit not found"
return
fi

output="$("$PLUGINKIT_BIN" -m -A -p com.apple.fileprovider-nonui 2>&1 || true)"
output="$("$PLUGINKIT_BIN" -m -A -D -vvv -p com.apple.fileprovider-nonui 2>&1 || true)"
count="$(grep -F -c "$PLUGIN_ID" <<<"$output" || true)"
expected_extension="$APP_PATH/Contents/Extensions/TCFSFileProvider.appex"

note "FileProvider plugin registrations for $PLUGIN_ID: $count"
case "$count" in
0) fail "FileProvider plugin registration missing: $PLUGIN_ID" ;;
1) ;;
*) fail "multiple FileProvider plugin registrations for $PLUGIN_ID: $count" ;;
esac

if [[ "$count" == "1" ]]; then
if grep -Fq "Path = $expected_extension" <<<"$output" \
|| grep -Fq "Parent Bundle = $APP_PATH" <<<"$output"; then
note "FileProvider plugin registration path: matches app path"
else
fail "FileProvider plugin registration does not point at expected app path: $APP_PATH"
fi
fi
}

check_status() {
Expand Down
36 changes: 32 additions & 4 deletions scripts/test-macos-tcfs-rollout-readiness.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ assert_contains() {
fi
}

assert_not_contains() {
local file="$1"
local unexpected="$2"

if grep -Fq -- "$unexpected" "$file"; then
printf 'expected not to find %s in %s\n' "$unexpected" "$file" >&2
printf '%s\n' '--- output ---' >&2
cat "$file" >&2
exit 1
fi
}

assert_not_exists() {
local path="$1"
if [[ -e "$path" ]]; then
Expand Down Expand Up @@ -125,11 +137,20 @@ fi
EOF
cat >"$FAKE_BIN/launchctl" <<'EOF'
#!/usr/bin/env bash
printf 'service = dev.tinyland.tcfsd\n'
case "${1:-}" in
list)
printf '123\t0\tdev.tinyland.tcfsd\n'
;;
*)
exit 2
;;
esac
EOF
cat >"$FAKE_BIN/pluginkit" <<'EOF'
#!/usr/bin/env bash
printf '+ io.tinyland.tcfs.fileprovider(0.2.0)\n'
printf ' Path = %s/Contents/Extensions/TCFSFileProvider.appex\n' "${TCFS_FAKE_PLUGIN_APP_PATH:-$TCFS_APP_PATH}"
printf ' Parent Bundle = %s\n' "${TCFS_FAKE_PLUGIN_APP_PATH:-$TCFS_APP_PATH}"
EOF
cat >"$FAKE_BIN/spctl" <<'EOF'
#!/usr/bin/env bash
Expand All @@ -138,8 +159,8 @@ EOF
cat >"$FAKE_BIN/PlistBuddy" <<EOF
#!/usr/bin/env bash
case "\$*" in
*"ProgramArguments:2"*)
printf '/bin/wait4path /nix/store && exec $TMPDIR/fake-tcfsd-daemon-darwin\n'
*"ProgramArguments:0"*)
printf '/bin/sh\n'
;;
*"CFBundleShortVersionString"*"TCFSFileProvider.appex"*)
printf '0.2.0\n'
Expand Down Expand Up @@ -173,7 +194,9 @@ env "${COMMON_ENV[@]}" \

assert_contains "$PASS_OUT" "lab tummycrypt rev: f22f36ca7307e1db32f2ed4b7b0e69e3b7cea04e"
assert_contains "$PASS_OUT" "tcfs version: tcfs 0.12.14"
assert_contains "$PASS_OUT" "launch agent command inspection: not executed"
assert_contains "$PASS_OUT" "launch agent command: configured (argv0: /bin/sh)"
assert_contains "$PASS_OUT" "launch agent command inspection: redacted"
assert_not_contains "$PASS_OUT" "fake-tcfsd-daemon-darwin"
assert_contains "$PASS_OUT" "tcfs status: returned within 2s"
assert_contains "$PASS_OUT" "rollout-readiness=pass"
assert_not_exists "$WRAPPER_SENTINEL"
Expand All @@ -185,4 +208,9 @@ assert_fails_contains \
assert_contains "$TMPDIR/failure.combined" "rollout-readiness=fail"
assert_not_exists "$WRAPPER_SENTINEL"

assert_fails_contains \
"FileProvider plugin registration does not point at expected app path" \
env "${COMMON_ENV[@]}" TCFS_FAKE_PLUGIN_APP_PATH="$TMPDIR/shadow/TCFSProvider.app" "$SCRIPT"
assert_contains "$TMPDIR/failure.combined" "rollout-readiness=fail"

printf 'macOS TCFS rollout readiness tests passed\n'