File size: 6,822 Bytes
4e23b01 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | #!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
PACKAGE_DIR="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
REPO_ROOT="$(cd -- "${PACKAGE_DIR}/../.." && pwd)"
workspace_slug="$(
basename -- "${REPO_ROOT}" \
| tr '[:upper:]' '[:lower:]' \
| tr -cs 'a-z0-9_.-' '-' \
| sed -e 's/^[^a-z0-9]*//' -e 's/[^a-z0-9]*$//' \
| cut -c1-48
)"
if [[ -z "${workspace_slug}" ]]; then
workspace_slug="workspace"
fi
workspace_hash="$(printf '%s' "${REPO_ROOT}" | cksum | awk '{print $1}')"
RUN_ID="${KIMI_SERVER_E2E_RUN_ID:-${workspace_slug}-${workspace_hash}}"
BASE_IMAGE="${KIMI_SERVER_E2E_BASE_IMAGE:-kimi-server-e2e-base:${RUN_ID}}"
IMAGE="${KIMI_SERVER_E2E_IMAGE:-kimi-server-e2e:${RUN_ID}}"
CONTAINER="${KIMI_SERVER_E2E_CONTAINER:-kimi-server-e2e-${RUN_ID}}"
STATE_ROOT="${KIMI_SERVER_E2E_STATE_ROOT:-${HOME}/.kimi-code-server-dev}"
PORT="${KIMI_SERVER_E2E_PORT:-58627}"
KIMI_HOME_HOST="${KIMI_SERVER_E2E_KIMI_HOME_HOST:-${STATE_ROOT}/docker-e2e/${RUN_ID}/kimi-code-home}"
KIMI_HOME_CONTAINER="/data/docker-e2e/kimi-code-home"
SEED_HOME_HOST="${KIMI_SERVER_E2E_SEED_KIMI_HOME_HOST:-${STATE_ROOT}/kimi-home/kimi-code-home}"
if [[ -n "${KIMI_SERVER_E2E_REPORT_DIR_HOST:-}" ]]; then
REPORT_DIR_HOST="${KIMI_SERVER_E2E_REPORT_DIR_HOST}"
REPORT_ROOT_HOST="$(dirname -- "${REPORT_DIR_HOST}")"
REPORT_DIR_NAME="$(basename -- "${REPORT_DIR_HOST}")"
else
REPORT_ROOT_HOST="${KIMI_SERVER_E2E_REPORT_ROOT_HOST:-${STATE_ROOT}/server-e2e-reports/docker/${RUN_ID}}"
REPORT_DIR_NAME="latest"
REPORT_DIR_HOST="${REPORT_ROOT_HOST}/${REPORT_DIR_NAME}"
fi
REPORT_ROOT_CONTAINER="/data/server-e2e-reports/docker"
REPORT_DIR_CONTAINER="${REPORT_ROOT_CONTAINER}/${REPORT_DIR_NAME}"
TMPDIR_CONTAINER="/data/docker-e2e/tmp"
NM_ROOT="${STATE_ROOT}/docker-e2e/${RUN_ID}/nm"
workspace_node_modules=(
"root:/workspace/kimi-code/node_modules"
"apps_kimi-code:/workspace/kimi-code/apps/kimi-code/node_modules"
"apps_kimi-web:/workspace/kimi-code/apps/kimi-web/node_modules"
"apps_vis:/workspace/kimi-code/apps/vis/node_modules"
"apps_vis_server:/workspace/kimi-code/apps/vis/server/node_modules"
"apps_vis_web:/workspace/kimi-code/apps/vis/web/node_modules"
"docs:/workspace/kimi-code/docs/node_modules"
"pkg_kap-server:/workspace/kimi-code/packages/kap-server/node_modules"
"pkg_server-e2e:/workspace/kimi-code/packages/klient/node_modules"
"pkg_kaos:/workspace/kimi-code/packages/kaos/node_modules"
"pkg_kosong:/workspace/kimi-code/packages/kosong/node_modules"
"pkg_migration-legacy:/workspace/kimi-code/packages/migration-legacy/node_modules"
"pkg_node-sdk:/workspace/kimi-code/packages/node-sdk/node_modules"
"pkg_oauth:/workspace/kimi-code/packages/oauth/node_modules"
"pkg_protocol:/workspace/kimi-code/packages/protocol/node_modules"
"pkg_services:/workspace/kimi-code/packages/services/node_modules"
"pkg_telemetry:/workspace/kimi-code/packages/telemetry/node_modules"
)
mkdir -p "${STATE_ROOT}" "${KIMI_HOME_HOST}" "${REPORT_DIR_HOST}" "${NM_ROOT}"
for mount in "${workspace_node_modules[@]}"; do
mkdir -p "${NM_ROOT}/${mount%%:*}"
done
# Seed only auth/config into the isolated docker-e2e home. Never copy server
# locks, sessions, uploaded files, or reports from the compose server home.
if [[ -f "${SEED_HOME_HOST}/config.toml" && ! -f "${KIMI_HOME_HOST}/config.toml" ]]; then
cp "${SEED_HOME_HOST}/config.toml" "${KIMI_HOME_HOST}/config.toml"
fi
if [[ -d "${SEED_HOME_HOST}/credentials" && ! -d "${KIMI_HOME_HOST}/credentials" ]]; then
cp -R "${SEED_HOME_HOST}/credentials" "${KIMI_HOME_HOST}/credentials"
fi
if [[ "${KIMI_SERVER_E2E_SKIP_BUILD:-0}" != "1" ]]; then
docker build -t "${BASE_IMAGE}" -f "${REPO_ROOT}/Dockerfile" "${REPO_ROOT}"
docker build \
-t "${IMAGE}" \
-f "${PACKAGE_DIR}/Dockerfile" \
--build-arg "BASE_IMAGE=${BASE_IMAGE}" \
"${REPO_ROOT}"
fi
docker rm -f "${CONTAINER}" >/dev/null 2>&1 || true
read -r -d '' container_script <<'EOS' || true
set -euo pipefail
cd /workspace/kimi-code
mkdir -p "${KIMI_CODE_HOME}/server" "${KIMI_SERVER_E2E_REPORT_DIR}" "${TMPDIR}" /data/server-e2e-reports/docker
rm -f "${KIMI_CODE_HOME}/server/lock"
if [[ ! -e /workspace/kimi-code/node_modules/.modules.yaml || ! -e /workspace/kimi-code/packages/klient/node_modules/ws ]]; then
echo "[server-e2e:docker] installing pnpm deps"
pnpm install --frozen-lockfile
else
echo "[server-e2e:docker] pnpm deps already present"
fi
server_log="/data/server-e2e-reports/docker/server.log"
: > "${server_log}"
echo "[server-e2e:docker] starting server on container-local ${KIMI_SERVER_URL}"
pnpm dev:server -- \
--host 127.0.0.1 \
--port "${KIMI_SERVER_E2E_PORT}" \
--log-level debug \
--debug-endpoints \
>"${server_log}" 2>&1 &
server_pid=$!
cleanup() {
status=$?
if kill -0 "${server_pid}" >/dev/null 2>&1; then
kill "${server_pid}" >/dev/null 2>&1 || true
wait "${server_pid}" >/dev/null 2>&1 || true
fi
exit "${status}"
}
trap cleanup EXIT INT TERM
ready=0
for attempt in $(seq 1 90); do
if curl -fsS "${KIMI_SERVER_URL}/api/v1/meta" >/tmp/server-meta.json 2>/tmp/server-curl.err; then
ready=1
echo "[server-e2e:docker] server ready: $(cat /tmp/server-meta.json)"
break
fi
if ! kill -0 "${server_pid}" >/dev/null 2>&1; then
echo "[server-e2e:docker] server exited before readiness" >&2
tail -n 200 "${server_log}" >&2 || true
exit 1
fi
sleep 1
done
if [[ "${ready}" != "1" ]]; then
echo "[server-e2e:docker] server did not become ready within 90s" >&2
cat /tmp/server-curl.err >&2 || true
tail -n 200 "${server_log}" >&2 || true
exit 1
fi
cd /workspace/kimi-code/packages/klient
pnpm test
EOS
docker_args=(
run
--rm
--init
--name "${CONTAINER}"
--workdir /workspace/kimi-code/packages/klient
--env "KIMI_CODE_HOME=${KIMI_HOME_CONTAINER}"
--env "KIMI_SERVER_E2E_PORT=${PORT}"
--env "KIMI_SERVER_URL=http://127.0.0.1:${PORT}"
--env "KIMI_SERVER_E2E_REPORT_DIR=${REPORT_DIR_CONTAINER}"
--env "TMPDIR=${TMPDIR_CONTAINER}"
--env "TERM=xterm-256color"
--env "TZ=Asia/Shanghai"
--env "npm_config_store_dir=/workspace/kimi-code/node_modules/.pnpm-store"
--env "npm_config_package_import_method=copy"
--volume "${REPO_ROOT}:/workspace/kimi-code:ro"
--volume "${KIMI_HOME_HOST}:${KIMI_HOME_CONTAINER}"
--volume "${REPORT_ROOT_HOST}:${REPORT_ROOT_CONTAINER}"
)
for mount in "${workspace_node_modules[@]}"; do
docker_args+=(--volume "${NM_ROOT}/${mount%%:*}:${mount#*:}")
done
echo "[server-e2e:docker] running ${IMAGE} without host port publishing"
set +e
docker "${docker_args[@]}" "${IMAGE}" bash -lc "${container_script}"
status=$?
set -e
echo "[server-e2e:docker] report: ${REPORT_DIR_HOST}/index.html"
echo "[server-e2e:docker] server log: ${REPORT_ROOT_HOST}/server.log"
exit "${status}"
|