Skip to content

Commit d7bc1b8

Browse files
committed
test harness for quick checks
1 parent 734f02d commit d7bc1b8

3 files changed

Lines changed: 800 additions & 1 deletion

File tree

Makefile

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,50 @@ USE_NODE = NVM_SH="$${NVM_DIR:-$$HOME/.nvm}/nvm.sh"; \
3333
[ -s "$$NVM_SH" ] || NVM_SH="$$(brew --prefix nvm 2>/dev/null)/nvm.sh"; \
3434
if [ -s "$$NVM_SH" ]; then . "$$NVM_SH" >/dev/null && nvm install >/dev/null 2>&1 && nvm use >/dev/null 2>&1; fi
3535

36-
.PHONY: all help dev dev-pulse build-ui build build-cli run run-cli install-air install-pulse clean test test-cli install-ui setup-workspace work-init work-clean docs docker-image docker-run cleanup-enterprise mod-tidy test-integrations-py test-integrations-ts install-playwright run-e2e run-e2e-ui run-e2e-headed format ui
36+
# Decides how to expose secrets to a recipe. Set via:
37+
# INFISICAL=1 -> always wrap commands with `infisical run --path <p> --` (non-interactive)
38+
# INFISICAL=0 -> always source ./.env (non-interactive)
39+
# INFISICAL_PATH=/x -> override the Infisical secret path (default /local)
40+
# unset + tty -> prompt the user
41+
# unset + CI -> default to dotenv silently
42+
# After invoking `$(EXPOSE_ENV);`, prefix each command with `$$CMD_PREFIX` so it inherits the chosen secrets.
43+
# Use as: `$(EXPOSE_ENV); $$CMD_PREFIX <your command>`
44+
define EXPOSE_ENV
45+
if [ -n "$$INFISICAL" ]; then \
46+
case "$$INFISICAL" in \
47+
1|y|Y|yes|YES|true|TRUE) USE_INFISICAL=1 ;; \
48+
*) USE_INFISICAL=0 ;; \
49+
esac; \
50+
elif [ -t 0 ]; then \
51+
printf "$(CYAN)Use Infisical to expose secrets to this run? [y/N] $(NC)"; \
52+
read ENV_ANSWER; \
53+
case "$$ENV_ANSWER" in \
54+
y|Y|yes|YES) USE_INFISICAL=1 ;; \
55+
*) USE_INFISICAL=0 ;; \
56+
esac; \
57+
else \
58+
USE_INFISICAL=0; \
59+
fi; \
60+
if [ "$$USE_INFISICAL" = "1" ]; then \
61+
if ! which infisical > /dev/null 2>&1; then \
62+
$(ECHO) "$(RED)infisical CLI not found. Install: https://infisical.com/docs/cli/overview$(NC)"; \
63+
exit 1; \
64+
fi; \
65+
INFISICAL_PATH_VAL="$${INFISICAL_PATH:-/local}"; \
66+
$(ECHO) "$(GREEN)Secrets via Infisical (path=$$INFISICAL_PATH_VAL)$(NC)"; \
67+
CMD_PREFIX="infisical run --path $$INFISICAL_PATH_VAL --"; \
68+
else \
69+
if [ -f .env ]; then \
70+
$(ECHO) "$(YELLOW)Loading environment variables from .env...$(NC)"; \
71+
set -a; . ./.env; set +a; \
72+
else \
73+
$(ECHO) "$(YELLOW)No .env found - using current shell environment$(NC)"; \
74+
fi; \
75+
CMD_PREFIX=""; \
76+
fi
77+
endef
78+
79+
.PHONY: all help dev dev-pulse build-ui build build-cli run run-cli install-air install-pulse clean test test-cli install-ui setup-workspace work-init work-clean docs docker-image docker-run cleanup-enterprise mod-tidy test-integrations-py test-integrations-ts install-playwright run-e2e run-e2e-ui run-e2e-headed format ui install-newman run-provider-harness-test
3780

3881
all: help
3982

@@ -1484,3 +1527,96 @@ test-cli: install-gotestsum ## Run CLI tests
14841527
--format=$(GOTESTSUM_FORMAT) \
14851528
--junitfile=../$(TEST_REPORTS_DIR)/cli.xml \
14861529
-- ./...
1530+
1531+
install-newman: ## Install newman + htmlextra reporter if not already installed
1532+
@$(USE_NODE); which newman > /dev/null 2>&1 || ($(ECHO) "$(YELLOW)Installing newman...$(NC)" && npm install -g newman)
1533+
@$(USE_NODE); npm list -g newman-reporter-htmlextra > /dev/null 2>&1 || ($(ECHO) "$(YELLOW)Installing newman-reporter-htmlextra...$(NC)" && npm install -g newman-reporter-htmlextra)
1534+
@$(ECHO) "$(GREEN)Newman + htmlextra are ready$(NC)"
1535+
1536+
run-provider-harness-test: install-newman ## Run the Bifrost provider-harness Postman collection via newman, opens an interactive HTML viewer with resend support afterwards. Set CI=1 to skip the viewer and just emit tmp/newman-report.html as a CI artifact. Prompts for Infisical-vs-.env (Usage: make run-provider-harness-test [BASE_URL=...] [APP_DIR=...] [FOLDER="..."] [ENV_FILE=...] [INFISICAL=1|0] [INFISICAL_PATH=/local] [VIEWER_PORT=8090] [CI=1])
1537+
@mkdir -p tmp
1538+
@$(EXPOSE_ENV); \
1539+
BASE_URL_VAL="$(or $(BASE_URL),http://localhost:8080)"; \
1540+
APP_DIR_VAL="$(or $(APP_DIR),tests/integrations/python)"; \
1541+
VIEWER_PORT_VAL="$(or $(VIEWER_PORT),8090)"; \
1542+
STARTED_BY_US=0; \
1543+
cleanup() { \
1544+
if [ -f tmp/harness-viewer.pid ]; then \
1545+
VPID=$$(cat tmp/harness-viewer.pid); \
1546+
kill $$VPID 2>/dev/null; \
1547+
rm -f tmp/harness-viewer.pid; \
1548+
fi; \
1549+
if [ "$$STARTED_BY_US" = "1" ] && [ -f tmp/bifrost-dev.pid ]; then \
1550+
BPID=$$(cat tmp/bifrost-dev.pid); \
1551+
$(ECHO) "$(YELLOW)Stopping Bifrost (pid $$BPID) - we started it...$(NC)"; \
1552+
kill $$BPID 2>/dev/null; \
1553+
pkill -P $$BPID 2>/dev/null; \
1554+
rm -f tmp/bifrost-dev.pid; \
1555+
fi; \
1556+
}; \
1557+
preempt_viewer_port() { \
1558+
if [ -f tmp/harness-viewer.pid ]; then \
1559+
OLD=$$(cat tmp/harness-viewer.pid); \
1560+
if kill -0 $$OLD 2>/dev/null; then \
1561+
$(ECHO) "$(YELLOW)Killing orphaned viewer pid $$OLD from a prior run...$(NC)"; \
1562+
kill $$OLD 2>/dev/null; sleep 1; \
1563+
fi; \
1564+
rm -f tmp/harness-viewer.pid; \
1565+
fi; \
1566+
pkill -f "tests/e2e/api/runners/harness-viewer.mjs" 2>/dev/null || true; \
1567+
if command -v lsof > /dev/null 2>&1 && lsof -ti tcp:$$VIEWER_PORT_VAL > /dev/null 2>&1; then \
1568+
$(ECHO) "$(YELLOW)Port $$VIEWER_PORT_VAL still in use - freeing it...$(NC)"; \
1569+
lsof -ti tcp:$$VIEWER_PORT_VAL | xargs kill 2>/dev/null || true; \
1570+
sleep 1; \
1571+
fi; \
1572+
}; \
1573+
trap cleanup EXIT INT TERM HUP; \
1574+
if curl -fsS --max-time 2 "$$BASE_URL_VAL/health" > /dev/null 2>&1; then \
1575+
$(ECHO) "$(GREEN)Bifrost already running at $$BASE_URL_VAL$(NC)"; \
1576+
else \
1577+
$(ECHO) "$(YELLOW)Bifrost not running - launching 'make dev' (APP_DIR=$$APP_DIR_VAL) in background...$(NC)"; \
1578+
$$CMD_PREFIX $(MAKE) dev APP_DIR="$$APP_DIR_VAL" > tmp/bifrost-dev.log 2>&1 & \
1579+
echo $$! > tmp/bifrost-dev.pid; \
1580+
STARTED_BY_US=1; \
1581+
$(ECHO) "$(CYAN)Waiting for Bifrost /health to respond (up to 60s)...$(NC)"; \
1582+
for i in $$(seq 1 30); do \
1583+
if curl -fsS --max-time 2 "$$BASE_URL_VAL/health" > /dev/null 2>&1; then \
1584+
$(ECHO) "$(GREEN)Bifrost is up$(NC)"; break; \
1585+
fi; \
1586+
sleep 2; \
1587+
done; \
1588+
if ! curl -fsS --max-time 2 "$$BASE_URL_VAL/health" > /dev/null 2>&1; then \
1589+
$(ECHO) "$(RED)Bifrost did not become healthy. See tmp/bifrost-dev.log$(NC)"; \
1590+
exit 1; \
1591+
fi; \
1592+
fi; \
1593+
$(ECHO) "$(YELLOW)Running Postman collection via newman against $$BASE_URL_VAL...$(NC)"; \
1594+
$(USE_NODE); $$CMD_PREFIX newman run tests/e2e/api/collections/provider-harness.json \
1595+
--env-var "baseUrl=$$BASE_URL_VAL" \
1596+
$(if $(ENV_FILE),--environment $(ENV_FILE),) \
1597+
$(if $(FOLDER),--folder "$(FOLDER)",) \
1598+
--reporters cli,json,htmlextra \
1599+
--reporter-json-export tmp/newman-report.json \
1600+
--reporter-htmlextra-export tmp/newman-report.html \
1601+
--reporter-htmlextra-title "Bifrost Provider Harness" \
1602+
--reporter-htmlextra-darkTheme; \
1603+
NEWMAN_EXIT=$$?; \
1604+
$(ECHO) "$(GREEN)Newman finished. Reports: tmp/newman-report.json + tmp/newman-report.html$(NC)"; \
1605+
if [ -n "$(CI)" ] || [ -n "$$CI" ]; then \
1606+
$(ECHO) "$(CYAN)CI mode - skipping interactive viewer. Upload tmp/newman-report.html as a workflow artifact.$(NC)"; \
1607+
else \
1608+
preempt_viewer_port; \
1609+
$(ECHO) "$(CYAN)Launching interactive viewer on http://localhost:$$VIEWER_PORT_VAL (Bifrost stays up for resend)...$(NC)"; \
1610+
$(USE_NODE); node tests/e2e/api/runners/harness-viewer.mjs --report tmp/newman-report.json --port $$VIEWER_PORT_VAL & \
1611+
VIEWER_PID=$$!; \
1612+
echo $$VIEWER_PID > tmp/harness-viewer.pid; \
1613+
wait $$VIEWER_PID; \
1614+
VIEWER_EXIT=$$?; \
1615+
rm -f tmp/harness-viewer.pid; \
1616+
if [ $$VIEWER_EXIT -ne 0 ]; then \
1617+
$(ECHO) "$(RED)Viewer exited with code $$VIEWER_EXIT (see message above).$(NC)"; \
1618+
else \
1619+
$(ECHO) "$(GREEN)Viewer closed.$(NC)"; \
1620+
fi; \
1621+
fi; \
1622+
exit $$NEWMAN_EXIT

0 commit comments

Comments
 (0)