mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-05 11:18:24 +00:00
Switch fetch_fixtures.py's default relay and the parity tests' docs from search-staging to the production search relay, and re-record tools/search-parity/fixture.json from it. The new corpus keeps the same shape: 8 cases x 8 events, every event satisfies its NIP-01 filter, and 8 of 64 carry no literal occurrence of their search term, so the KDoc's numbers still hold; its quoted examples are swapped for ones in the new recording. Also fixes the script's usage line, which pointed at a stale output path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BvR9ox7m91GLFUARuqj8o5
77 lines
3.2 KiB
Python
Executable File
77 lines
3.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Record real answers from a live vespa-relay so the local search engine can be tested
|
|
against them offline.
|
|
|
|
Run by hand when the fixture needs refreshing; the test that consumes its output never
|
|
touches the network, so `./gradlew test` stays hermetic and offline.
|
|
|
|
./gradlew :cli:installDist
|
|
tools/search-parity/fetch_fixtures.py > tools/search-parity/fixture.json
|
|
|
|
Each case pins the filter FIELDS (kinds/tags/window) as flags rather than folding them into
|
|
the search string, so the test can rebuild the identical NIP-01 Filter and assert our matcher
|
|
agrees with the relay about every event it chose to return.
|
|
"""
|
|
import json
|
|
import os
|
|
import shlex
|
|
import subprocess
|
|
import sys
|
|
|
|
RELAY = os.environ.get("RELAY", "wss://search.brainstorm.world")
|
|
AMY = os.environ.get("AMY", os.path.join(os.getcwd(), "cli/build/install/amy/bin/amy"))
|
|
# The relay gates and ranks results through the searcher's web of trust, and answers an
|
|
# anonymous query with nothing at all. `include:spam` waives that gate, which is what makes
|
|
# this fixture reproducible: the alternative, `observer:<pubkey>`, ties every recorded answer
|
|
# to one account's trust graph and re-records differently as that graph moves.
|
|
#
|
|
# It does NOT make the relay lexical. Measured on this corpus, results still include events
|
|
# carrying no literal occurrence of the term — asked for `"open source"` it returns "FOSS you say
|
|
# will save you". Retrieval is semantic; see the parity test for why that means text results are
|
|
# not compared.
|
|
LENS = os.environ.get("LENS", "include:spam")
|
|
LIMIT = os.environ.get("LIMIT", "8")
|
|
TIMEOUT = os.environ.get("TIMEOUT", "30")
|
|
|
|
# name, search terms, filter flags
|
|
CASES = [
|
|
("text_single", "bitcoin", ["--kind", "1"]),
|
|
("text_two_words", "bitcoin lightning", ["--kind", "1"]),
|
|
("text_longform", "nostr", ["--kind", "30023"]),
|
|
("tag_hashtag", "bitcoin", ["--kind", "1", "--tag", "t=bitcoin"]),
|
|
("window_since", "nostr", ["--kind", "1", "--since", "1700000000"]),
|
|
("window_until", "nostr", ["--kind", "1", "--until", "1800000000"]),
|
|
("kinds_union", "nostr", ["--kind", "1,30023"]),
|
|
("phrase_quoted", '"open source"', ["--kind", "1"]),
|
|
]
|
|
|
|
|
|
def fetch(terms, flags):
|
|
search = f"{terms} {LENS}"
|
|
cmd = [AMY, "fetch", *flags, "--search", search, "--limit", LIMIT,
|
|
"--relay", RELAY, "--timeout", TIMEOUT, "--json"]
|
|
try:
|
|
out = subprocess.run(cmd, capture_output=True, text=True, timeout=int(TIMEOUT) + 30)
|
|
return search, json.loads(out.stdout).get("events", [])
|
|
except Exception as e: # a relay that is down must not silently produce an empty fixture
|
|
print(f"FAILED {' '.join(shlex.quote(c) for c in cmd)}: {e}", file=sys.stderr)
|
|
raise
|
|
|
|
|
|
def main():
|
|
if not os.access(AMY, os.X_OK):
|
|
sys.exit("amy not built: ./gradlew :cli:installDist")
|
|
cases = []
|
|
for name, terms, flags in CASES:
|
|
search, events = fetch(terms, flags)
|
|
print(f"{name:16s} {len(events):3d} events", file=sys.stderr)
|
|
cases.append({"name": name, "terms": terms, "flags": flags,
|
|
"search": search, "events": events})
|
|
json.dump({"relay": RELAY, "lens": LENS, "cases": cases},
|
|
sys.stdout, indent=1, sort_keys=True)
|
|
print()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|