Skip to content

Commit 4b5235c

Browse files
committed
feat(test-suite): rewrite fhevm-cli as Bun/TypeScript CLI
Replace the 340-line bash fhevm-cli with a typed Bun/TypeScript CLI using Commander.js. The new CLI orchestrates the same Docker Compose services with the same arguments, but with typed modules for env management, deploy DAG, test dispatch, and docker operations. New modules: - dag.ts: 13-step deploy DAG with explicit dependency edges - env.ts: version defaults + env file preparation (replaces cp+sed) - docker.ts: compose up/down, waitForService, getContainerIp - executor.ts: Bun.spawn wrapper with dry-run recording for testing - cache.ts: BuildKit local cache env var computation - test-suites.ts: suite name → grep pattern mapping - 10 command files: up, test, clean, logs, restart, upgrade, pause, unpause, status, doctor Test coverage (100 tests, 856 assertions): - Unit tests: dag, env, cache, test-suites - Migration tests: structural diff against bash deploy script, argument parity against original bash CLI (pinned to a4a9aa4) - Live e2e runner for comparing both CLIs against a Docker stack The original fhevm-cli becomes a 3-line bash passthrough.
1 parent a4a9aa4 commit 4b5235c

32 files changed

+3543
-338
lines changed

test-suite/fhevm/bun.lock

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test-suite/fhevm/fhevm-cli

Lines changed: 1 addition & 338 deletions
Original file line numberDiff line numberDiff line change
@@ -1,340 +1,3 @@
11
#!/bin/bash
2-
set -e
3-
4-
BLUE='\033[0;34m'
5-
LIGHT_BLUE='\033[1;34m'
6-
GREEN='\033[0;32m'
7-
RED='\033[0;31m'
8-
YELLOW='\033[0;33m'
9-
PURPLE='\033[0;35m'
10-
CYAN='\033[0;36m'
11-
BOLD='\033[1m'
12-
RESET='\033[0m'
13-
142
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
15-
PROJECT="fhevm"
16-
17-
# Default versions for the fhevm stack.
18-
19-
# KMS connector services.
20-
export CONNECTOR_DB_MIGRATION_VERSION=${CONNECTOR_DB_MIGRATION_VERSION:-"v0.11.0-1"}
21-
export CONNECTOR_GW_LISTENER_VERSION=${CONNECTOR_GW_LISTENER_VERSION:-"v0.11.0-1"}
22-
export CONNECTOR_KMS_WORKER_VERSION=${CONNECTOR_KMS_WORKER_VERSION:-"v0.11.0-1"}
23-
export CONNECTOR_TX_SENDER_VERSION=${CONNECTOR_TX_SENDER_VERSION:-"v0.11.0-1"}
24-
25-
# Coprocessor services.
26-
export COPROCESSOR_DB_MIGRATION_VERSION=${COPROCESSOR_DB_MIGRATION_VERSION:-"v0.11.0-1"}
27-
export COPROCESSOR_GW_LISTENER_VERSION=${COPROCESSOR_GW_LISTENER_VERSION:-"v0.11.0-1"}
28-
export COPROCESSOR_HOST_LISTENER_VERSION=${COPROCESSOR_HOST_LISTENER_VERSION:-"v0.11.0-1"}
29-
export COPROCESSOR_TX_SENDER_VERSION=${COPROCESSOR_TX_SENDER_VERSION:-"v0.11.0-1"}
30-
export COPROCESSOR_TFHE_WORKER_VERSION=${COPROCESSOR_TFHE_WORKER_VERSION:-"v0.11.0-1"}
31-
export COPROCESSOR_SNS_WORKER_VERSION=${COPROCESSOR_SNS_WORKER_VERSION:-"v0.11.0-1"}
32-
export COPROCESSOR_ZKPROOF_WORKER_VERSION=${COPROCESSOR_ZKPROOF_WORKER_VERSION:-"v0.11.0-1"}
33-
34-
# Gateway and Host contracts.
35-
export GATEWAY_VERSION=${GATEWAY_VERSION:-"v0.11.0-1"}
36-
export HOST_VERSION=${HOST_VERSION:-"v0.11.0-1"}
37-
38-
# Other services.
39-
export CORE_VERSION=${CORE_VERSION:-"v0.13.0-rc.2"}
40-
export RELAYER_VERSION=${RELAYER_VERSION:-"v0.9.0-rc.1"}
41-
export RELAYER_MIGRATE_VERSION=${RELAYER_MIGRATE_VERSION:-"v0.9.0-rc.1"}
42-
export TEST_SUITE_VERSION=${TEST_SUITE_VERSION:-"v0.11.0-1"}
43-
44-
45-
function print_logo() {
46-
echo -e "${LIGHT_BLUE}"
47-
echo " ______ _ _ ______ __ __ __ __"
48-
echo " | ____| | | | | | ____| \ \ / / | \/ |"
49-
echo " | |__ | |__| | | |__ \ \ / / | \ / |"
50-
echo " | __| | __ | | __| \ \/ / | |\/| |"
51-
echo " | | | | | | | |____ \ / | | | |"
52-
echo " |_| |_| |_| |______| \/ |_| |_|"
53-
echo -e "${RESET}"
54-
}
55-
56-
function usage {
57-
print_logo
58-
echo -e "${BOLD}Usage:${RESET} ${YELLOW}fhevm-cli${RESET} ${CYAN}COMMAND [OPTIONS]${RESET}"
59-
echo
60-
echo -e "${BOLD}${LIGHT_BLUE}Commands:${RESET}"
61-
echo -e " ${YELLOW}deploy${RESET} ${CYAN}[--build] [--local]${RESET} WIP: Deploy the full fhevm stack (optionally rebuild images)"
62-
echo -e " ${YELLOW}pause${RESET} ${CYAN}[CONTRACTS]${RESET} Pause specific contracts (host|gateway)"
63-
echo -e " ${YELLOW}unpause${RESET} ${CYAN}[CONTRACTS]${RESET} Unpause specific contracts (host|gateway)"
64-
echo -e " ${YELLOW}test${RESET} ${CYAN}[TYPE]${RESET} Run tests (input-proof|user-decryption|public-decryption|delegated-user-decryption|random|random-subset|operators|erc20|debug)"
65-
echo -e " ${YELLOW}upgrade${RESET} ${CYAN}[SERVICE]${RESET} Upgrade specific service (host|gateway|connector|coprocessor|relayer|test-suite)"
66-
echo -e " ${YELLOW}clean${RESET} Remove all containers and volumes"
67-
echo -e " ${YELLOW}logs${RESET} ${CYAN}[SERVICE]${RESET} View logs for a specific service"
68-
echo -e " ${YELLOW}help${RESET} Display this help message"
69-
echo
70-
echo -e "${BOLD}${LIGHT_BLUE}Test Options:${RESET}"
71-
echo -e " ${CYAN}-v, --verbose${RESET} Enable verbose output"
72-
echo -e " ${CYAN}-n, --network NAME${RESET} Specify network (default: ${GREEN}staging${RESET})"
73-
echo -e " ${CYAN}-g, --grep PATTERN${RESET} Override default test pattern"
74-
echo -e " ${CYAN}-r, --no-relayer${RESET} Disable Rust relayer"
75-
echo -e " ${CYAN}--no-hardhat-compile${RESET} Skip Hardhat compilation step"
76-
echo
77-
echo -e "${BOLD}${LIGHT_BLUE}Examples:${RESET}"
78-
echo -e " ${PURPLE}./fhevm-cli deploy${RESET}"
79-
echo -e " ${PURPLE}./fhevm-cli deploy --build${RESET}"
80-
echo -e " ${PURPLE}./fhevm-cli deploy --local${RESET}"
81-
echo -e " ${PURPLE}./fhevm-cli test input-proof${RESET}"
82-
echo -e " ${PURPLE}./fhevm-cli test input-proof --no-hardhat-compile${RESET}"
83-
echo -e " ${PURPLE}./fhevm-cli test user-decryption ${RESET}"
84-
echo -e " ${PURPLE}./fhevm-cli test public-decrypt-http-ebool ${RESET}"
85-
echo -e " ${PURPLE}./fhevm-cli test public-decrypt-http-mixed -n staging${RESET}"
86-
echo -e " ${PURPLE}./fhevm-cli test erc20${RESET}"
87-
echo -e " ${PURPLE}./fhevm-cli upgrade coprocessor${RESET}"
88-
echo -e "${BLUE}============================================================${RESET}"
89-
}
90-
91-
COMMAND=$1
92-
shift
93-
94-
# Show help if no command is provided
95-
if [ -z "$COMMAND" ]; then
96-
usage
97-
exit 0
98-
fi
99-
100-
case $COMMAND in
101-
deploy)
102-
print_logo
103-
echo -e "${LIGHT_BLUE}${BOLD}[DEPLOY] Deploying fhevm stack...${RESET}"
104-
DEPLOY_ARGS=()
105-
while (( "$#" )); do
106-
case "$1" in
107-
--build)
108-
DEPLOY_ARGS+=("--build")
109-
shift
110-
;;
111-
--local|--dev)
112-
DEPLOY_ARGS+=("--local")
113-
shift
114-
;;
115-
*)
116-
echo -e "${RED}[ERROR]${RESET} ${BOLD}Unknown argument for deploy: $1${RESET}"
117-
usage
118-
exit 1
119-
;;
120-
esac
121-
done
122-
"${SCRIPT_DIR}/scripts/deploy-fhevm-stack.sh" "${DEPLOY_ARGS[@]}"
123-
echo -e "${GREEN}${BOLD} [SUCCESS] fhevm stack deployment complete!${RESET}"
124-
;;
125-
126-
pause)
127-
print_logo
128-
CONTRACTS=$1
129-
if [[ ! $CONTRACTS =~ ^(gateway|host)$ ]]; then
130-
echo -e "${RED}[ERROR]${RESET} ${BOLD}Unknown service: $CONTRACTS${RESET}"
131-
usage
132-
exit 1
133-
fi
134-
135-
echo -e "${LIGHT_BLUE}[PAUSE]${RESET} ${BOLD}Pausing $CONTRACTS...${RESET}"
136-
docker compose -p "${PROJECT}" -f "${SCRIPT_DIR}/docker-compose/${CONTRACTS}-pause-docker-compose.yml" up -d
137-
# Wait for the pause service to complete
138-
echo -e "${YELLOW}[WAIT]${RESET} ${BOLD}Waiting for pause operation to complete...${RESET}"
139-
docker compose -p "${PROJECT}" -f "${SCRIPT_DIR}/docker-compose/${CONTRACTS}-pause-docker-compose.yml" wait ${CONTRACTS}-sc-pause
140-
echo -e "${GREEN}[SUCCESS]${RESET} ${BOLD}$CONTRACTS paused successfully${RESET}"
141-
;;
142-
143-
unpause)
144-
print_logo
145-
CONTRACTS=$1
146-
if [[ ! $CONTRACTS =~ ^(gateway|host)$ ]]; then
147-
echo -e "${RED}[ERROR]${RESET} ${BOLD}Unknown service: $CONTRACTS${RESET}"
148-
usage
149-
exit 1
150-
fi
151-
152-
echo -e "${LIGHT_BLUE}[UNPAUSE]${RESET} ${BOLD}Unpausing $CONTRACTS...${RESET}"
153-
docker compose -p "${PROJECT}" -f "${SCRIPT_DIR}/docker-compose/${CONTRACTS}-unpause-docker-compose.yml" up -d
154-
# Wait for the unpause service to complete
155-
echo -e "${YELLOW}[WAIT]${RESET} ${BOLD}Waiting for unpause operation to complete...${RESET}"
156-
docker compose -p "${PROJECT}" -f "${SCRIPT_DIR}/docker-compose/${CONTRACTS}-unpause-docker-compose.yml" wait ${CONTRACTS}-sc-unpause
157-
echo -e "${GREEN}[SUCCESS]${RESET} ${BOLD}$CONTRACTS unpaused successfully${RESET}"
158-
;;
159-
160-
test)
161-
print_logo
162-
TEST_TYPE=$1
163-
shift
164-
165-
VERBOSE=""
166-
NETWORK="staging"
167-
GREP=""
168-
NO_RELAYER=""
169-
NO_COMPILE=""
170-
171-
while (( "$#" )); do
172-
case "$1" in
173-
-v|--verbose)
174-
VERBOSE="-v"
175-
shift
176-
;;
177-
-n|--network)
178-
if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then
179-
NETWORK="$2"
180-
shift 2
181-
else
182-
echo -e "${RED}[ERROR]${RESET} ${BOLD}Network argument missing${RESET}"
183-
usage
184-
exit 1
185-
fi
186-
;;
187-
-g|--grep)
188-
if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then
189-
GREP="$2"
190-
shift 2
191-
else
192-
echo -e "${RED}[ERROR]${RESET} ${BOLD}Grep pattern missing${RESET}"
193-
usage
194-
exit 1
195-
fi
196-
;;
197-
-r|--no-relayer)
198-
NO_RELAYER="-r"
199-
shift
200-
;;
201-
--no-hardhat-compile)
202-
NO_COMPILE="--no-hardhat-compile"
203-
shift
204-
;;
205-
*)
206-
echo -e "${RED}[ERROR]${RESET} ${BOLD}Unknown option: $1${RESET}"
207-
usage
208-
exit 1
209-
;;
210-
esac
211-
done
212-
213-
docker_args=("./run-tests.sh")
214-
if [ -n "$VERBOSE" ]; then
215-
docker_args+=("-v")
216-
fi
217-
docker_args+=("-n" "$NETWORK")
218-
if [ -n "$NO_RELAYER" ]; then
219-
docker_args+=("-r")
220-
fi
221-
if [ -n "$NO_COMPILE" ]; then
222-
docker_args+=("--no-hardhat-compile")
223-
fi
224-
225-
if [ -n "$GREP" ]; then
226-
docker_args+=("-g" "$GREP")
227-
else
228-
case $TEST_TYPE in
229-
input-proof)
230-
log_message="${LIGHT_BLUE}${BOLD}[TEST] INPUT PROOF (uint64)${RESET}"
231-
docker_args+=("-g" "test user input uint64")
232-
;;
233-
input-proof-compute-decrypt)
234-
log_message="${LIGHT_BLUE}${BOLD}[TEST] INPUT PROOF (uint64)${RESET}"
235-
docker_args+=("-g" "test add 42 to uint64 input and decrypt")
236-
;;
237-
user-decryption)
238-
log_message="${LIGHT_BLUE}${BOLD}[TEST] USER DECRYPTION${RESET}"
239-
docker_args+=("-g" "test user decrypt")
240-
;;
241-
delegated-user-decryption)
242-
log_message="${LIGHT_BLUE}${BOLD}[TEST] DELEGATED USER DECRYPTION${RESET}"
243-
docker_args+=("-g" "test delegated user decrypt")
244-
;;
245-
public-decryption)
246-
log_message="${LIGHT_BLUE}${BOLD}[TEST] PUBLIC DECRYPTION${RESET}"
247-
docker_args+=("-g" "test async decrypt (uint.*|ebytes.* trivial|ebytes64 non-trivial|ebytes256 non-trivial with snapshot|addresses|several addresses)")
248-
;;
249-
erc20)
250-
log_message="${LIGHT_BLUE}${BOLD}[TEST] ERC20${RESET}"
251-
docker_args+=("-g" "should transfer tokens between two users.")
252-
;;
253-
public-decrypt-http-ebool)
254-
log_message="${LIGHT_BLUE}${BOLD}[TEST] PUBLIC DECRYPTION OVER HTTP FOR EBOOL${RESET}"
255-
docker_args+=("-g" "test HTTPPublicDecrypt ebool")
256-
;;
257-
public-decrypt-http-mixed)
258-
log_message="${LIGHT_BLUE}${BOLD}[TEST] PUBLIC DECRYPTION OVER HTTP FOR MIXED${RESET}"
259-
docker_args+=("-g" "test HTTPPublicDecrypt mixed")
260-
;;
261-
operators)
262-
log_message="${LIGHT_BLUE}${BOLD}[TEST] OPERATORS${RESET}"
263-
docker_args+=("--parallel" "-g" "test operator|FHEVM manual operations")
264-
;;
265-
random)
266-
log_message="${LIGHT_BLUE}${BOLD}[TEST] RANDOM OPERATORS${RESET}"
267-
docker_args+=("-g" "generate and decrypt|generating rand in reverting sub-call|upper bound and decrypt")
268-
;;
269-
random-subset)
270-
log_message="${LIGHT_BLUE}${BOLD}[TEST] RANDOM OPERATORS (SUBSET)${RESET}"
271-
docker_args+=("-g" "64 bits generate and decrypt|generating rand in reverting sub-call|64 bits generate with upper bound and decrypt")
272-
;;
273-
paused-host-contracts)
274-
log_message="${LIGHT_BLUE}${BOLD}[TEST] PAUSED HOST CONTRACTS${RESET}"
275-
docker_args+=("-g" "test paused host.*")
276-
;;
277-
paused-gateway-contracts)
278-
log_message="${LIGHT_BLUE}${BOLD}[TEST] PAUSED GATEWAY CONTRACTS${RESET}"
279-
docker_args+=("-g" "test paused gateway.*")
280-
;;
281-
debug)
282-
echo -e "${LIGHT_BLUE}${BOLD}[DEBUG] Starting debug session...${RESET}"
283-
docker exec -it fhevm-test-suite-e2e-debug bash
284-
;;
285-
*)
286-
echo -e "${RED}[ERROR]${RESET} ${BOLD}Unknown test type: $TEST_TYPE${RESET}"
287-
usage
288-
exit 1
289-
;;
290-
esac
291-
fi
292-
if [ "$TEST_TYPE" != "debug" ]; then
293-
echo -e "${log_message}"
294-
docker exec fhevm-test-suite-e2e-debug "${docker_args[@]}"
295-
fi
296-
;;
297-
298-
help|-h|--help)
299-
usage
300-
exit 0
301-
;;
302-
303-
upgrade)
304-
print_logo
305-
SERVICE=$1
306-
if [[ ! $SERVICE =~ ^(minio|core|gateway-node|gateway-sc|gateway-mocked-payment|host-node|host-sc|kms-connector|coprocessor|relayer|test-suite)$ ]]; then
307-
echo -e "${RED}[ERROR]${RESET} ${BOLD}Unknown service: $SERVICE${RESET}"
308-
usage
309-
exit 1
310-
fi
311-
312-
echo -e "${LIGHT_BLUE}[UPGRADE]${RESET} ${BOLD}Upgrading $SERVICE...${RESET}"
313-
docker compose -p "${PROJECT}" --env-file "${SCRIPT_DIR}/env/staging/.env.${SERVICE}.local" -f "${SCRIPT_DIR}/docker-compose/${SERVICE}-docker-compose.yml" up -d
314-
echo -e "${GREEN}[SUCCESS]${RESET} ${BOLD}$SERVICE upgraded successfully${RESET}"
315-
;;
316-
317-
clean)
318-
echo -e "${LIGHT_BLUE}[CLEAN]${RESET} ${BOLD}Cleaning up FHEVM stack...${RESET}"
319-
docker compose -p "${PROJECT}" down -v --remove-orphans
320-
echo -e "${GREEN}[SUCCESS]${RESET} ${BOLD}FHEVM stack cleaned successfully${RESET}"
321-
;;
322-
323-
logs)
324-
SERVICE=$1
325-
if [ -z "${SERVICE}" ]; then
326-
echo -e "${RED}[ERROR]${RESET} ${BOLD}Service name is required${RESET}"
327-
usage
328-
exit 1
329-
fi
330-
331-
echo -e "${LIGHT_BLUE}[LOGS]${RESET} ${BOLD}Showing logs for $SERVICE...${RESET}"
332-
docker logs "${SERVICE}"
333-
;;
334-
335-
*)
336-
echo -e "${RED}[ERROR]${RESET} ${BOLD}Unknown command: ${COMMAND}${RESET}"
337-
usage
338-
exit 1
339-
;;
340-
esac
3+
exec bun run "$SCRIPT_DIR/src/index.ts" "$@"

test-suite/fhevm/package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "@fhevm/cli",
3+
"version": "0.1.0",
4+
"type": "module",
5+
"bin": {
6+
"fhevm": "./src/index.ts"
7+
},
8+
"dependencies": {
9+
"commander": "^14.0.1",
10+
"chalk": "^5.4.0"
11+
},
12+
"devDependencies": {
13+
"@types/bun": "latest",
14+
"typescript": "^5.5.0"
15+
}
16+
}

0 commit comments

Comments
 (0)