99586fbe7e
There is no installed base to protect, so the self-contained
`--data-dir P` escape hatch goes away entirely. amy now has exactly
one layout — the production multi-account one — and tests exercise
that same code path. Drops one global flag, one DataDir construction
mode, and the "tests use a different code path than users" footgun.
Layout (unchanged from the previous commits — just the only mode now):
~/.amy/
├── current # `amy use NAME` marker
├── shared/
│ └── events-store/ # FsEventStore, one per machine
├── alice/
│ ├── identity.json
│ ├── state.json
│ ├── aliases.json # {"alice": "<own npub>"} after init
│ └── marmot/
└── bob/ ...
`DataDir.DEFAULT_ROOT` reads `$HOME` directly (falling back to
`user.home`) because JDK 21 resolves `user.home` via getpwuid and
ignores `$HOME` — which would have broken the standard CLI test
isolation pattern of `HOME=/tmp/foo amy …` (the same convention
git, gpg, npm follow).
Test sweep:
- `cli/tests/headless/helpers.sh`, `cli/tests/dm/setup.sh`,
`cli/tests/cache/cache-headless.sh` wrappers all switch to
`HOME=$STATE_DIR amy --name X …`.
- `ensure_identity_for` drops its `dir` parameter; the function and
every harness call site go through `--name` only.
- `A_DIR`/`B_DIR`/`D_DIR` get repointed at `$STATE_DIR/.amy/X`. The
one consumer (`cache-headless.sh`'s T6 `relays.json` check) still
works since it's just a path probe.
- `cli/tests/dm/tests-dm.sh` ghost identities get their own
short-lived `$HOME` so they don't pollute the main test root.
Cache-test T4 inverts: pre-shared-store, "B has not seen A → first
profile show is a relay miss, second is a cache hit" tested
per-account caching. With one shared events-store, B's first lookup
of A is already a cache hit because A wrote kind:0 there during
bootstrap. T4 now asserts that — drops the stale "second lookup hits
cache" half. T7 (no-identity maintenance verbs) gets a fresh fake
`$HOME` plus a throwaway `--name` so the empty store has no inherited
events.
Docs (README + DEVELOPMENT) rewritten to match — quick-start now uses
`amy --name alice create`, the on-disk-layout section shows the new
tree, and the global-flags table replaces `--data-dir` with `--name`
plus the new `amy use` verb.
109 lines
3.3 KiB
Bash
Executable File
109 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# dm-interop-headless.sh — zero-prompt NIP-17 DM interop harness.
|
|
#
|
|
# Two `amy` processes (Identity A and Identity D) talk to each other
|
|
# through a local nostr-rs-relay on ws://127.0.0.1:$RELAY_PORT. No
|
|
# whitenoise-rs, no Marmot, no public internet traffic.
|
|
#
|
|
# Usage: ./dm-interop-headless.sh [--port N] [--no-build]
|
|
#
|
|
set -uo pipefail
|
|
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd -- "$SCRIPT_DIR/../../.." && pwd)"
|
|
TESTS_DIR="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
|
STATE_DIR="$SCRIPT_DIR/state-dm-headless"
|
|
LOG_DIR="$STATE_DIR/logs"
|
|
# Per-account dirs under the same fake $HOME=$STATE_DIR so amy treats
|
|
# this as one user with two accounts (production layout).
|
|
A_DIR="$STATE_DIR/.amy/A"
|
|
D_DIR="$STATE_DIR/.amy/D"
|
|
|
|
RUN_TS="$(date +%Y%m%d-%H%M%S)"
|
|
LOG_FILE="$LOG_DIR/run-$RUN_TS.log"
|
|
RESULTS_FILE="$STATE_DIR/results-$RUN_TS.tsv"
|
|
|
|
AMY_BIN="$REPO_ROOT/cli/build/install/amy/bin/amy"
|
|
|
|
# Share the nostr-rs-relay checkout with the Marmot harness to avoid
|
|
# rebuilding it twice. Override RELAY_REPO / RELAY_DATA if you want full
|
|
# isolation between runs.
|
|
# Bind the loopback relay to 127.0.0.2 rather than 127.0.0.1 so Quartz's
|
|
# `isLocalHost()` filter doesn't silently strip it out of the kind:10050
|
|
# inbox events during recipient-relay resolution. 127.0.0.2 is still pure
|
|
# loopback — no network traffic, no config needed.
|
|
RELAY_HOST="${RELAY_HOST:-127.0.0.2}"
|
|
RELAY_REPO="${RELAY_REPO:-$TESTS_DIR/marmot/state-headless/nostr-rs-relay}"
|
|
RELAY_BIN="$RELAY_REPO/target/release/nostr-rs-relay"
|
|
RELAY_DATA="$STATE_DIR/relay"
|
|
RELAY_PORT="${RELAY_PORT:-8090}"
|
|
RELAY_URL="ws://$RELAY_HOST:$RELAY_PORT"
|
|
NO_BUILD=0
|
|
|
|
A_NPUB=""
|
|
A_HEX=""
|
|
D_NPUB=""
|
|
D_HEX=""
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--port) RELAY_PORT="$2"; RELAY_URL="ws://$RELAY_HOST:$RELAY_PORT"; shift ;;
|
|
--host) RELAY_HOST="$2"; RELAY_URL="ws://$RELAY_HOST:$RELAY_PORT"; shift ;;
|
|
--no-build) NO_BUILD=1 ;;
|
|
-h|--help)
|
|
sed -n '3,12p' "${BASH_SOURCE[0]}" | sed 's/^# \?//'
|
|
exit 0 ;;
|
|
*) printf 'unknown flag: %s\n' "$1" >&2; exit 2 ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
mkdir -p "$STATE_DIR" "$LOG_DIR"
|
|
: >"$LOG_FILE"
|
|
: >"$RESULTS_FILE"
|
|
|
|
# Reuse the logging + result helpers shared between every harness.
|
|
# lib.sh declares wn-specific helpers too — harmless when unused.
|
|
# shellcheck source=../lib.sh
|
|
source "$TESTS_DIR/lib.sh"
|
|
|
|
# Reuse start_local_relay / stop_local_relay from the Marmot harness's
|
|
# setup.sh — the relay lifecycle is identical. preflight() there also
|
|
# builds whitenoise-rs, which we don't need; setup.sh in this dir
|
|
# defines a slimmer preflight_dm().
|
|
# shellcheck source=../marmot/setup.sh
|
|
source "$TESTS_DIR/marmot/setup.sh"
|
|
# shellcheck source=setup.sh
|
|
source "$SCRIPT_DIR/setup.sh"
|
|
# shellcheck source=../headless/helpers.sh
|
|
source "$TESTS_DIR/headless/helpers.sh"
|
|
# shellcheck source=tests-dm.sh
|
|
source "$SCRIPT_DIR/tests-dm.sh"
|
|
|
|
cleanup() {
|
|
local rc=$?
|
|
trap - EXIT INT TERM HUP
|
|
stop_local_relay
|
|
print_summary
|
|
exit "$rc"
|
|
}
|
|
trap cleanup EXIT
|
|
trap 'exit 130' INT
|
|
trap 'exit 143' TERM
|
|
trap 'exit 129' HUP
|
|
|
|
banner "Amethyst NIP-17 DM headless interop ($RUN_TS)"
|
|
preflight_dm
|
|
start_local_relay
|
|
ensure_identity_for A
|
|
ensure_identity_for D
|
|
configure_relays_dm
|
|
|
|
test_01_dm_text_round_trip
|
|
test_02_dm_list_surfaces_history
|
|
test_03_dm_send_rejects_no_inbox
|
|
test_04_dm_send_allow_fallback
|
|
test_05_dm_file_reference_round_trip
|
|
test_06_dm_list_since_filter
|