run.sh 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. #!/usr/bin/env bash
  2. set -u
  3. export NODE_NO_WARNINGS=1
  4. cd "$(dirname "$0")/.."
  5. GREEN=$'\e[32m'
  6. RED=$'\e[31m'
  7. YELLOW=$'\e[33m'
  8. BOLD=$'\e[1m'
  9. RESET=$'\e[0m'
  10. SSB_DIR="$HOME/.ssb"
  11. SSB_BACKUP=""
  12. ASSUME_YES=0
  13. RESTORE=0
  14. SKIP_ISOLATION=0
  15. CLEAN_ALL=0
  16. SEED=0
  17. DUMMY_ONLY=0
  18. for arg in "$@"; do
  19. case "$arg" in
  20. -y|--yes) ASSUME_YES=1 ;;
  21. --restore) RESTORE=1 ;;
  22. --no-isolation) SKIP_ISOLATION=1 ;;
  23. --seed) SEED=1 ;;
  24. dummy|--dummy) SEED=1; DUMMY_ONLY=1 ;;
  25. clean-all|--clean-all) CLEAN_ALL=1 ;;
  26. -h|--help)
  27. cat <<EOF
  28. Usage: $0 [options]
  29. Options:
  30. -y, --yes skip confirmation prompt
  31. --restore restore your original ~/.ssb on exit (DESTROYS test data)
  32. Default: keep the test ~/.ssb so you can boot oasis and
  33. visually inspect what the tests produced.
  34. --no-isolation run tests against current ~/.ssb (DANGEROUS — may conflict)
  35. --seed after all mock tests pass, write dummy content to the
  36. isolated ~/.ssb via the REAL SSB models (so you can boot
  37. oasis and visually inspect modules with realistic data).
  38. dummy skip tests AND isolation; publish real content into your
  39. running oasis (~/.ssb) so the network gets filled with
  40. dummy data you can immediately see in the browser. Requires
  41. oasis to be running (sh oasis.sh) in another terminal.
  42. clean-all delete all test reports in results/ AND the test ~/.ssb,
  43. then exit (does NOT run tests). If a backup exists, it is
  44. restored first so you don't lose your real data.
  45. -h, --help this message
  46. Each run generates test/results/unit_test_<timestamp>.md
  47. EOF
  48. exit 0
  49. ;;
  50. esac
  51. done
  52. if [ "$CLEAN_ALL" = "1" ]; then
  53. echo "${YELLOW}${BOLD}clean-all:${RESET}"
  54. # Restore latest backup if there is one
  55. latest_backup=$(ls -dt "$HOME"/.ssb-bak-* 2>/dev/null | head -1)
  56. if [ -n "$latest_backup" ] && [ -d "$SSB_DIR" ]; then
  57. echo " found backup: $latest_backup"
  58. if [ "$ASSUME_YES" != "1" ]; then
  59. if [ ! -t 0 ]; then
  60. echo "${RED}stdin is not a TTY; refusing to prompt. Pass --yes to skip prompt.${RESET}"
  61. exit 2
  62. fi
  63. read -r -p " remove test ~/.ssb and restore your original from latest backup? [y/N] " ans
  64. case "$ans" in
  65. y|Y|yes|YES) ;;
  66. *) echo " aborted."; exit 1 ;;
  67. esac
  68. fi
  69. rm -rf "$SSB_DIR"
  70. mv "$latest_backup" "$SSB_DIR" && echo " ${GREEN}~/.ssb restored from $latest_backup${RESET}"
  71. elif [ -n "$latest_backup" ] && [ ! -d "$SSB_DIR" ]; then
  72. mv "$latest_backup" "$SSB_DIR" && echo " ${GREEN}~/.ssb restored from $latest_backup${RESET}"
  73. elif [ -d "$SSB_DIR" ]; then
  74. if [ "$ASSUME_YES" != "1" ]; then
  75. if [ ! -t 0 ]; then
  76. echo "${RED}stdin is not a TTY; refusing to prompt. Pass --yes to skip prompt.${RESET}"
  77. exit 2
  78. fi
  79. read -r -p " no backup found. Delete current ~/.ssb anyway? [y/N] " ans
  80. case "$ans" in
  81. y|Y|yes|YES) rm -rf "$SSB_DIR" && echo " ${GREEN}~/.ssb deleted.${RESET}" ;;
  82. *) echo " ~/.ssb left intact." ;;
  83. esac
  84. else
  85. rm -rf "$SSB_DIR" && echo " ${GREEN}~/.ssb deleted.${RESET}"
  86. fi
  87. else
  88. echo " no ~/.ssb to clean."
  89. fi
  90. # Clean other backup dirs
  91. bak_count=$(ls -d "$HOME"/.ssb-bak-* 2>/dev/null | wc -l)
  92. if [ "$bak_count" -gt 0 ]; then
  93. for b in "$HOME"/.ssb-bak-*; do
  94. [ -e "$b" ] && rm -rf "$b" && echo " removed: $b"
  95. done
  96. fi
  97. # Clean results
  98. if [ -d "test/results" ]; then
  99. n=$(ls test/results/unit_test_*.md 2>/dev/null | wc -l)
  100. rm -f test/results/unit_test_*.md
  101. echo " ${GREEN}removed $n report(s) from test/results/${RESET}"
  102. fi
  103. echo "${GREEN}clean-all done.${RESET}"
  104. exit 0
  105. fi
  106. isolate_ssb() {
  107. if [ "$SKIP_ISOLATION" = "1" ]; then
  108. echo "${YELLOW}⚠ skipping ~/.ssb isolation (--no-isolation set). Tests may conflict with running oasis.${RESET}"
  109. return
  110. fi
  111. if [ ! -e "$SSB_DIR" ] && [ ! -L "$SSB_DIR" ]; then
  112. return
  113. fi
  114. local ts=$(date +%Y%m%d_%H%M%S)
  115. SSB_BACKUP="${SSB_DIR}-bak-${ts}"
  116. echo ""
  117. echo "${YELLOW}${BOLD}⚠ WARNING${RESET}"
  118. echo "${YELLOW}This will move your current ${BOLD}${SSB_DIR}${RESET}${YELLOW} → ${BOLD}${SSB_BACKUP}${RESET}"
  119. echo "${YELLOW}and create a fresh empty ${SSB_DIR} for the tests.${RESET}"
  120. echo "${YELLOW}On exit the test ~/.ssb is KEPT (visual inspection); your original stays at the backup path.${RESET}"
  121. echo "${YELLOW}If oasis is currently running, STOP IT FIRST.${RESET}"
  122. if [ "$ASSUME_YES" != "1" ]; then
  123. if [ ! -t 0 ]; then
  124. echo "${RED}stdin is not a TTY; refusing to prompt. Pass --yes to skip prompt.${RESET}"
  125. exit 2
  126. fi
  127. read -r -p "Continue? [y/N] " ans
  128. case "$ans" in
  129. y|Y|yes|YES) ;;
  130. *) echo "aborted."; exit 1 ;;
  131. esac
  132. fi
  133. mv "$SSB_DIR" "$SSB_BACKUP" || { echo "${RED}failed to move $SSB_DIR${RESET}"; exit 3; }
  134. mkdir -p "$SSB_DIR"
  135. echo "${GREEN}~/.ssb isolated → $SSB_BACKUP${RESET}"
  136. }
  137. restore_ssb() {
  138. if [ -z "$SSB_BACKUP" ]; then return; fi
  139. if [ "$RESTORE" != "1" ]; then
  140. echo ""
  141. echo "${YELLOW}Test ~/.ssb left in place for visual inspection.${RESET}"
  142. echo "${YELLOW} test data: $SSB_DIR${RESET}"
  143. echo "${YELLOW} your original: $SSB_BACKUP${RESET}"
  144. echo ""
  145. echo "${YELLOW}To boot oasis against the test data:${RESET} sh oasis.sh"
  146. echo "${YELLOW}To restore your original later:${RESET} rm -rf $SSB_DIR && mv $SSB_BACKUP $SSB_DIR"
  147. return
  148. fi
  149. echo ""
  150. echo "${YELLOW}Restoring ~/.ssb from backup...${RESET}"
  151. rm -rf "$SSB_DIR" 2>/dev/null
  152. mv "$SSB_BACKUP" "$SSB_DIR" && echo "${GREEN}~/.ssb restored.${RESET}" || echo "${RED}failed to restore — backup left at $SSB_BACKUP${RESET}"
  153. }
  154. trap restore_ssb EXIT INT TERM
  155. if [ "$DUMMY_ONLY" = "1" ]; then
  156. echo "${YELLOW}=== dummy mode: publishing real content to your running oasis (no isolation, no tests) ===${RESET}"
  157. echo "${YELLOW}Make sure oasis is currently running (sh oasis.sh) so the seed can connect via the local SSB socket.${RESET}"
  158. node test/seed.js
  159. rc=$?
  160. if [ "$rc" -eq 0 ]; then
  161. echo ""
  162. echo "${GREEN}Done. Refresh oasis in your browser to see the seeded content.${RESET}"
  163. else
  164. echo "${RED}seed.js exited with code $rc${RESET}"
  165. fi
  166. exit "$rc"
  167. fi
  168. isolate_ssb
  169. # -----------------------------------------------------------------------
  170. MODULES=(
  171. mods/crypto
  172. mods/tribes
  173. mods/sub-tribes
  174. mods/media/audios
  175. mods/media/videos
  176. mods/media/images
  177. mods/media/documents
  178. mods/media/bookmarks
  179. mods/forum
  180. mods/transfers
  181. mods/votes
  182. mods/events
  183. mods/tasks
  184. mods/chats
  185. mods/pads
  186. mods/maps
  187. mods/torrents
  188. mods/calendars
  189. mods/reports
  190. mods/market
  191. mods/jobs
  192. mods/projects
  193. mods/inhabitants
  194. mods/parliament
  195. mods/courts
  196. mods/opinions
  197. mods/activity
  198. mods/stats
  199. mods/blockchain
  200. mods/shops
  201. mods/pixelia
  202. mods/pm
  203. mods/feed
  204. mods/tags
  205. mods/search
  206. mods/trending
  207. mods/agenda
  208. mods/cv
  209. mods/favorites
  210. mods/banking
  211. mods/ai
  212. mods/profile
  213. mods/peers
  214. mods/multiuser
  215. )
  216. DATE=$(date +%Y-%m-%d_%H-%M-%S)
  217. REPORT_DIR="test/results"
  218. mkdir -p "$REPORT_DIR"
  219. REPORT="$REPORT_DIR/unit_test_${DATE}.md"
  220. # Working files
  221. TMP=$(mktemp -d)
  222. trap "rm -rf $TMP" EXIT
  223. total_passed=0
  224. total_failed=0
  225. total_tests_passed=0
  226. total_tests_run=0
  227. failed_modules=()
  228. passing_modules=()
  229. module_outputs=()
  230. for m in "${MODULES[@]}"; do
  231. if [ ! -d "test/$m" ]; then
  232. echo "${YELLOW}skip $m (no tests yet)${RESET}"
  233. continue
  234. fi
  235. output=$(node test/run.js "$m" 2>&1)
  236. echo "$output"
  237. echo "$output" > "$TMP/$(echo $m | tr '/' '_').out"
  238. summary=$(echo "$output" | grep -E "passed" | tail -1)
  239. if [ -z "$summary" ]; then
  240. total_failed=$((total_failed + 1))
  241. failed_modules+=("$m")
  242. continue
  243. fi
  244. pcount=$(echo "$summary" | sed -E 's/.*\[32m([0-9]+)\/([0-9]+) passed.*/\1/' | grep -E "^[0-9]+$" || echo 0)
  245. tcount=$(echo "$summary" | sed -E 's/.*\[32m([0-9]+)\/([0-9]+) passed.*/\2/' | grep -E "^[0-9]+$")
  246. if [ -z "$tcount" ]; then
  247. pcount=$(echo "$summary" | sed -E 's/.*\[3[12]m([0-9]+)\/([0-9]+) passed.*/\1/')
  248. tcount=$(echo "$summary" | sed -E 's/.*\[3[12]m([0-9]+)\/([0-9]+) passed.*/\2/')
  249. fi
  250. total_tests_passed=$((total_tests_passed + ${pcount:-0}))
  251. total_tests_run=$((total_tests_run + ${tcount:-0}))
  252. if echo "$summary" | grep -q "failed"; then
  253. total_failed=$((total_failed + 1))
  254. failed_modules+=("$m")
  255. else
  256. total_passed=$((total_passed + 1))
  257. passing_modules+=("$m")
  258. fi
  259. done
  260. echo ""
  261. echo "${YELLOW}=== Aggregate ===${RESET}"
  262. echo "${GREEN}Modules passing: $total_passed${RESET}"
  263. if [ "$total_failed" -gt 0 ]; then
  264. echo "${RED}Modules with failures: $total_failed${RESET}"
  265. for f in "${failed_modules[@]}"; do echo " - $f"; done
  266. fi
  267. # Generate the markdown report
  268. {
  269. echo "# Unit test report — $DATE"
  270. echo ""
  271. echo "**Tests passed:** $total_tests_passed / $total_tests_run"
  272. echo "**Modules passing:** $total_passed / ${#MODULES[@]}"
  273. if [ "$total_failed" -gt 0 ]; then
  274. echo "**Modules with failures:** $total_failed"
  275. fi
  276. echo ""
  277. echo "## ✅ Passing modules"
  278. echo ""
  279. for m in "${passing_modules[@]}"; do
  280. f="$TMP/$(echo $m | tr '/' '_').out"
  281. if [ -f "$f" ]; then
  282. summary=$(grep -E "passed in" "$f" | tail -1 | sed -E 's/\x1b\[[0-9;]*m//g')
  283. echo "- \`$m\` — $summary"
  284. grep -E "✓" "$f" | sed -E 's/\x1b\[[0-9;]*m//g' | sed 's/^ / - /'
  285. fi
  286. done
  287. if [ "$total_failed" -gt 0 ]; then
  288. echo ""
  289. echo "## ❌ Failing modules"
  290. echo ""
  291. for m in "${failed_modules[@]}"; do
  292. f="$TMP/$(echo $m | tr '/' '_').out"
  293. echo "### \`$m\`"
  294. echo ""
  295. if [ -f "$f" ]; then
  296. echo '```'
  297. cat "$f" | sed -E 's/\x1b\[[0-9;]*m//g'
  298. echo '```'
  299. else
  300. echo "_(no output captured)_"
  301. fi
  302. echo ""
  303. done
  304. fi
  305. echo ""
  306. echo "---"
  307. echo "_Generated by \`test/run.sh\` on $DATE._"
  308. } > "$REPORT"
  309. echo ""
  310. echo "${YELLOW}Report:${RESET} $REPORT"
  311. if [ "$SEED" = "1" ] && [ "$total_failed" -eq 0 ]; then
  312. echo ""
  313. echo "${YELLOW}=== Seeding dummy content into the test ~/.ssb ===${RESET}"
  314. node test/seed.js
  315. fi
  316. if [ "$total_failed" -gt 0 ]; then exit 1; fi
  317. exit 0