Skip to content

Commit 851e90b

Browse files
committed
test: run the hook tests with vfox plugin test, which finds them itself
1 parent df49c5b commit 851e90b

14 files changed

Lines changed: 253 additions & 255 deletions

‎.devcontainer/Dockerfile‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@
1717
# amd64/arm64 through Docker Desktop's Linux-container mode. It carries the
1818
# pinned Go toolchain the E2E suites and the local checks need, matching the
1919
# setup-go version CI uses, plus the Lua and license tooling pinned in the
20-
# lint and license workflows.
20+
# lint and license workflows, and the vfox release that runs the hook tests
21+
# (vfox plugin test) in the test workflow.
2122
#
2223
# The suites themselves run testcontainers against the host daemon through
2324
# the socket mounted by devcontainer.json (Docker-out-of-Docker), so the
2425
# target containers are spawned exactly as a native CI runner spawns them.
2526
#
26-
# The image is multi-arch (linux/amd64 and linux/arm64); the Lua downloads
27-
# below select their asset per target arch.
27+
# The image is multi-arch (linux/amd64 and linux/arm64); the Lua and vfox
28+
# downloads below select their asset per target arch.
2829

2930
FROM golang:1.27.1
3031

@@ -34,9 +35,10 @@ FROM golang:1.27.1
3435
COPY --from=docker:29-cli /usr/local/bin/docker /usr/local/bin/docker
3536

3637
# Keep the tool versions below in step with .github/workflows/lint.yml
37-
# (stylua-action's version and the `mise x aqua:...` line).
38+
# (stylua-action's version and the `mise x aqua:...` line) and test.yml (vfox).
3839
ARG STYLUA_VERSION=2.5.2
3940
ARG LUA_LANGUAGE_SERVER_VERSION=3.19.1
41+
ARG VFOX_VERSION=1.0.13
4042

4143
# Heredocs need BuildKit, which the dev container tooling uses by default. The
4244
# E2E target Dockerfiles stay on the chained-`;` form: testcontainers-go's
@@ -53,8 +55,8 @@ apt-get install --assume-yes --no-install-recommends \
5355
zip
5456
rm --recursive --force /var/lib/apt/lists/*
5557
case "$(dpkg --print-architecture)" in
56-
amd64) stylua_asset=stylua-linux-x86_64.zip; luals_asset="lua-language-server-${LUA_LANGUAGE_SERVER_VERSION}-linux-x64.tar.gz" ;;
57-
arm64) stylua_asset=stylua-linux-aarch64.zip; luals_asset="lua-language-server-${LUA_LANGUAGE_SERVER_VERSION}-linux-arm64.tar.gz" ;;
58+
amd64) stylua_asset=stylua-linux-x86_64.zip; luals_asset="lua-language-server-${LUA_LANGUAGE_SERVER_VERSION}-linux-x64.tar.gz"; vfox_dir="vfox_${VFOX_VERSION}_linux_x86_64" ;;
59+
arm64) stylua_asset=stylua-linux-aarch64.zip; luals_asset="lua-language-server-${LUA_LANGUAGE_SERVER_VERSION}-linux-arm64.tar.gz"; vfox_dir="vfox_${VFOX_VERSION}_linux_aarch64" ;;
5860
*) echo "FAIL unsupported architecture $(dpkg --print-architecture)" >&2; exit 1 ;;
5961
esac
6062
curl --fail --silent --show-error --location --output /tmp/stylua.zip \
@@ -67,8 +69,13 @@ mkdir --parents /opt/lua-language-server
6769
tar --extract --gzip --file /tmp/luals.tar.gz --directory /opt/lua-language-server
6870
rm --force /tmp/luals.tar.gz
6971
ln --symbolic /opt/lua-language-server/bin/lua-language-server /usr/local/bin/lua-language-server
72+
curl --fail --silent --show-error --location --output /tmp/vfox.tar.gz \
73+
"https://github.com/version-fox/vfox/releases/download/v${VFOX_VERSION}/${vfox_dir}.tar.gz"
74+
tar --extract --gzip --file /tmp/vfox.tar.gz --directory /usr/local/bin --strip-components=1 "${vfox_dir}/vfox"
75+
rm --force /tmp/vfox.tar.gz
7076
stylua --version
7177
lua-language-server --version
78+
vfox --version
7279
EOF
7380

7481
# License-header tooling at the versions pinned by .github/workflows/license.yml

‎.github/workflows/test.yml‎

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,32 @@ jobs:
3434
with:
3535
go-version: '1.24.0'
3636
cache: false
37-
# glua runs the one script it is given and passes the rest to it as `arg`,
38-
# so `glua tests/*_test.lua` would run the first file and pass. xargs -n1
39-
# starts a glua for each file instead, which the tests need: they replace
40-
# globals (os.getenv, package.preload) that the next file must not see.
41-
# -t prints each command, so the log names the file behind every result,
42-
# and xargs runs the rest after a failure and exits nonzero at the end.
43-
# With no test file the glob stays as written and glua fails on it.
44-
- name: Run the offline hook tests with vfox's Lua interpreter
37+
# vfox plugin test came with vfox 1.0.13. The release is pinned and its
38+
# checksum checked, as the actions are pinned by their commits; change the
39+
# two together to move to another release.
40+
- name: Install vfox
41+
env:
42+
VFOX_VERSION: 1.0.13
43+
VFOX_SHA256: 7ad0a4c82c8173f09393e09abecc3e27468253bab5fe53ffbf58f2b12b3fc768
4544
run: |
46-
printf '%s\0' tests/*_test.lua | xargs -0 -n1 -t go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1
45+
archive="$RUNNER_TEMP/vfox.tar.gz"
46+
curl --fail --silent --show-error --location --output "$archive" \
47+
"https://github.com/version-fox/vfox/releases/download/v${VFOX_VERSION}/vfox_${VFOX_VERSION}_linux_x86_64.tar.gz"
48+
echo "$VFOX_SHA256 $archive" | sha256sum --check
49+
mkdir "$RUNNER_TEMP/vfox"
50+
tar --extract --gzip --file "$archive" --directory "$RUNNER_TEMP/vfox" --strip-components=1 \
51+
"vfox_${VFOX_VERSION}_linux_x86_64/vfox"
52+
echo "$RUNNER_TEMP/vfox" >> "$GITHUB_PATH"
53+
# It finds tests/**/*_test.lua and runs each file in a VM of its own. A file
54+
# that does not call test.load() from vfox.test fails, and so does a run
55+
# that finds no test file.
56+
- name: Run the offline hook tests with vfox
57+
run: vfox plugin test .
58+
# PostInstall's shell script runs for real here, on directories the test
59+
# makes, and vfox plugin test disables os.execute. So this file is not a
60+
# *_test.lua, and it runs under glua, as it does on macOS below.
61+
- name: Test the macOS Java home layouts with vfox's Lua interpreter
62+
run: go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/post_install_layouts.lua
4763
macos-layout:
4864
runs-on: macos-latest
4965
steps:
@@ -55,4 +71,4 @@ jobs:
5571
go-version: '1.24.0'
5672
cache: false
5773
- name: Test actual macOS filesystem layouts
58-
run: go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/post_install_test.lua
74+
run: go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/post_install_layouts.lua

‎docs/development.md‎

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ lib/foojay.lua the Foojay request, and fixes to what it answers
1818
lib/github_mirror.lua the mirror of the downloads from GitHub
1919
lib/installed_version.lua matching against installed names
2020
lib/loongnix.lua the Loongnix archive
21-
tests/*_test.lua offline hook tests
21+
tests/*_test.lua offline hook tests, run by vfox plugin test
22+
tests/post_install_layouts.lua the macOS layouts PostInstall handles, with its real shell script
2223
tests/fixtures/loongnix/ a saved copy of the Loongnix archive listing
2324
tests/e2e/ container tests, see e2e.md
2425
Injection.lua type hints for what vfox injects, never loaded
@@ -69,21 +70,26 @@ SDKMAN spells some things differently (`jbr`, `21.0.12.fx-zulu`, `21.0.12-fx+1.1
6970

7071
## Tests
7172

72-
The hook tests run offline under `gopher-lua`, the Lua interpreter vfox embeds. Every `tests/*_test.lua` is a test, and a new one needs no entry anywhere:
73+
The hook tests run offline under `vfox plugin test`, which vfox 1.0.13 and later has. It finds every `tests/**/*_test.lua` and runs each file in a VM of its own, so a new test file needs no entry anywhere:
7374

7475
```bash
75-
printf '%s\0' tests/*_test.lua | xargs -0 -n1 -t go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1
76+
vfox plugin test .
77+
vfox plugin test . --file tests/pre_use_test.lua
7678
```
7779

78-
One file alone:
80+
Run it from the repository root. The Test Plugin workflow installs the release pinned in `.github/workflows/test.yml`, and the dev container carries the same one.
81+
82+
A test file calls `test.load()` from `vfox.test` once, and calls the real hooks through what it returns, as in `plugin:PreInstall({ version = "21-tem" })`. `test.load` takes the platform (`os`, `arch`), the environment variables (`env`) and a function that answers every HTTP request (`http`). The modules in `lib` can be required after it, and `RUNTIME.osType` and `RUNTIME.archType` can be changed to try another platform. See vfox's [Test and debug a plugin](https://vfox.dev/plugins/create/testing.html). The context and the result of a hook go through the decoding vfox does, so a hook that returns a bare string where vfox wants a table fails the test, and a string the result lacks comes back as `""`, not `nil`.
83+
84+
The VM disables `os.execute` and `io.popen`, so `tests/pre_install_test.lua` answers the `ldd --version` that decides between glibc and musl itself. It keeps Foojay's answers in a table at the top, keyed by `<distribution> [<version>]`, with `windows` or `macos` in front for those systems, and its `http` function sends them as JSON. Add the answer a new case needs there, and note the day you observed it.
85+
86+
`tests/post_install_layouts.lua` is the one test that is not a `*_test.lua`: it runs the shell script of `PostInstall` on directories it makes, which the VM does not allow. It runs under `gopher-lua`, the Lua interpreter vfox embeds:
7987

8088
```bash
81-
go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/pre_use_test.lua
89+
go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/post_install_layouts.lua
8290
```
8391

84-
Run them from the repository root. `glua` runs the one script it is given and passes the rest to it as `arg`, so `glua tests/*_test.lua` would run the first file and pass. `xargs -n1` starts one `glua` per file, because the files replace globals (`os.getenv`, `package.preload`) that the next one must not see, and it runs the rest after a failure. Every test file loads `tests/support.lua`, which stubs `vfox.strings`, and `tests/pre_install_test.lua` and `tests/loongnix_test.lua` stub `http` and `json` themselves. `tests/pre_install_test.lua` keeps Foojay's answers in a table at the top, keyed by `<distribution> [<version>]`, with `windows` or `macos` in front for those systems. Add the answer a new case needs there, and note the day you observed it. Lint, license headers and the container tests are in [e2e.md](e2e.md#local-checks).
85-
86-
vfox 1.0.13 and later also has `vfox plugin test`, which finds `tests/**/*_test.lua` by itself and runs each file with fresh globals. It fails all of these files: it requires a call to `test.load()` from `vfox.test`, which none of them makes, and its test VM disables `os.execute` and `io.popen` by default, which `tests/post_install_test.lua` (the shell script of `PostInstall`) and `tests/pre_install_test.lua` (`ldd --version` in `lib/foojay.lua`) run. So the tests run under `glua`.
92+
Lint, license headers and the container tests are in [e2e.md](e2e.md#local-checks).
8793

8894
To call a single hook against the real Foojay, vfox 1.0.13 and later has `vfox plugin run`. It does not register the plugin, and `--os` and `--arch` answer for another platform:
8995

‎docs/e2e.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
[中文](zh-CN/e2e.md) | [English](e2e.md)
44

5-
The offline Lua hook tests (`tests/*_test.lua`) run in the **Test Plugin**
5+
The offline Lua hook tests (`tests/*_test.lua` under `vfox plugin test`, and
6+
`tests/post_install_layouts.lua` under `glua`) run in the **Test Plugin**
67
workflow. The end-to-end suite runs in containers against real vfox on Linux
78
and Windows; each `vfox` x `distribution` combination gets its own throwaway
89
container. CI runs the suite natively on the stock runners (Docker plus Go
@@ -406,7 +407,8 @@ lua-language-server --check . --checklevel=Warning
406407

407408
```bash
408409
# Offline hook tests (.github/workflows/test.yml).
409-
printf '%s\0' tests/*_test.lua | xargs -0 -n1 -t go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1
410+
vfox plugin test .
411+
go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/post_install_layouts.lua
410412
```
411413

412414
```bash

‎docs/zh-CN/development.md‎

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ lib/foojay.lua 向 Foojay 发出的请求,以及对返回结
1818
lib/github_mirror.lua 从 GitHub 下载时用的镜像
1919
lib/installed_version.lua 与已安装的版本名做匹配
2020
lib/loongnix.lua Loongnix 归档
21-
tests/*_test.lua 离线的钩子测试
21+
tests/*_test.lua 离线的钩子测试,由 vfox plugin test 运行
22+
tests/post_install_layouts.lua PostInstall 处理的 macOS 目录结构,会真实执行它的 shell 脚本
2223
tests/fixtures/loongnix/ Loongnix 归档目录页的一份快照
2324
tests/e2e/ 容器测试,见 e2e.md
2425
Injection.lua vfox 注入对象的类型提示,不会被加载
@@ -69,21 +70,26 @@ SDKMAN 有些写法不同(`jbr`、`21.0.12.fx-zulu`、`21.0.12-fx+1.1-librca`
6970

7071
## 测试
7172

72-
钩子测试在离线状态下用 `gopher-lua` 运行,它就是 vfox 内嵌的 Lua 解释器。每个 `tests/*_test.lua` 都是一个测试,新增一个不需要在别处登记:
73+
钩子测试在离线状态下用 `vfox plugin test` 运行,vfox 1.0.13 及以后版本才有这个命令。它会找出所有 `tests/**/*_test.lua`,每个文件在自己的虚拟机里运行,所以新增一个测试文件不需要在别处登记:
7374

7475
```bash
75-
printf '%s\0' tests/*_test.lua | xargs -0 -n1 -t go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1
76+
vfox plugin test .
77+
vfox plugin test . --file tests/pre_use_test.lua
7678
```
7779

78-
只跑一个文件:
80+
请在仓库根目录运行。Test Plugin 工作流安装的是 `.github/workflows/test.yml` 里固定的那个版本,开发容器里装的也是它。
81+
82+
测试文件调用一次 `vfox.test` 的 `test.load()`,再通过它返回的对象调用真实的钩子,比如 `plugin:PreInstall({ version = "21-tem" })`。`test.load` 接受平台(`os`、`arch`)、环境变量(`env`)和一个回答所有 HTTP 请求的函数(`http`)。`lib` 里的模块要在它之后才能 `require`,修改 `RUNTIME.osType` 和 `RUNTIME.archType` 可以换一个平台来试。详见 vfox 的[测试与调试插件](https://vfox.dev/zh-hans/plugins/create/testing.html)。钩子的上下文和返回值会经过 vfox 自己的编解码,所以钩子在 vfox 要表的地方返回一个裸字符串,测试就会失败;返回值里缺的字符串会变成 `""`,而不是 `nil`。
83+
84+
测试用的虚拟机默认禁用 `os.execute` 和 `io.popen`,所以 `tests/pre_install_test.lua` 自己回答判断 glibc 还是 musl 的 `ldd --version`。它把 Foojay 的返回结果放在文件开头的一张表里,键是 `<发行版> [<版本>]`,Windows 和 macOS 的前面再分别加 `windows` 和 `macos`,它的 `http` 函数把这些结果以 JSON 发出去。新增用例需要的返回结果就加在那里,并注明观察到的日期。
85+
86+
`tests/post_install_layouts.lua` 是唯一不叫 `*_test.lua` 的测试:它在自己创建的目录上运行 `PostInstall` 的 shell 脚本,而测试虚拟机不允许这样做。它用 `gopher-lua` 运行,也就是 vfox 内嵌的 Lua 解释器:
7987

8088
```bash
81-
go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/pre_use_test.lua
89+
go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/post_install_layouts.lua
8290
```
8391

84-
请在仓库根目录运行。`glua` 只运行拿到的第一个脚本,其余参数作为 `arg` 传给它,所以 `glua tests/*_test.lua` 只会跑第一个文件,而且会通过。`xargs -n1` 为每个文件启动一个 `glua`,因为各个文件会替换全局的 `os.getenv`、`package.preload`,不能让下一个文件看到;某个文件失败后,其余文件照常运行。每个测试文件都会加载 `tests/support.lua`,它模拟 `vfox.strings`;`tests/pre_install_test.lua` 和 `tests/loongnix_test.lua` 还自己模拟了 `http` 和 `json`。`tests/pre_install_test.lua` 把 Foojay 的返回结果放在文件开头的一张表里,键是 `<发行版> [<版本>]`,Windows 和 macOS 的前面再分别加 `windows` 和 `macos`。新增用例需要的返回结果就加在那里,并注明观察到的日期。Lint、许可证头和容器测试见 [e2e.md](e2e.md#本地检查)。
85-
86-
vfox 1.0.13 及以后版本还有 `vfox plugin test`,它自己发现 `tests/**/*_test.lua`,并让每个文件用全新的全局状态运行。这里的文件它全部判为失败:它要求文件调用 `vfox.test` 的 `test.load()`,这些文件都没有调用;它的测试环境默认还禁用 `os.execute` 和 `io.popen`,而 `tests/post_install_test.lua`(`PostInstall` 的 shell 脚本)和 `tests/pre_install_test.lua`(`lib/foojay.lua` 里的 `ldd --version`)会运行它们。所以这些测试用 `glua` 运行。
92+
Lint、许可证头和容器测试见 [e2e.md](e2e.md#本地检查)。
8793

8894
想对着真实的 Foojay 调用单个钩子,可以用 vfox 1.0.13 及以后版本的 `vfox plugin run`。它不会注册插件,`--os` 和 `--arch` 可以模拟其他平台:
8995

‎docs/zh-CN/e2e.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[中文](e2e.md) | [English](../e2e.md)
44

5-
离线的 Lua 钩子测试(`tests/*_test.lua`)在 **Test Plugin** 工作流里运行。端到端套件在容器里针对真实的 vfox 运行,覆盖 Linux 和 Windows;每个 `vfox` x `distribution` 组合都有自己的一次性容器。CI 直接在标准 runner 上运行这套测试(Docker 加 `actions/setup-go` 提供的 Go)。本地则由仓库的开发容器在 Linux 上复现这一环境;Windows 上改用 Docker Compose runner 镜像,因为开发容器无法承载 Windows 容器镜像(见下文)。
5+
离线的 Lua 钩子测试(`tests/*_test.lua` 由 `vfox plugin test` 运行,`tests/post_install_layouts.lua` 由 `glua` 运行)在 **Test Plugin** 工作流里运行。端到端套件在容器里针对真实的 vfox 运行,覆盖 Linux 和 Windows;每个 `vfox` x `distribution` 组合都有自己的一次性容器。CI 直接在标准 runner 上运行这套测试(Docker 加 `actions/setup-go` 提供的 Go)。本地则由仓库的开发容器在 Linux 上复现这一环境;Windows 上改用 Docker Compose runner 镜像,因为开发容器无法承载 Windows 容器镜像(见下文)。
66

77
## 开发容器
88

@@ -195,7 +195,8 @@ lua-language-server --check . --checklevel=Warning
195195

196196
```bash
197197
# 离线的钩子测试(.github/workflows/test.yml)。
198-
printf '%s\0' tests/*_test.lua | xargs -0 -n1 -t go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1
198+
vfox plugin test .
199+
go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/post_install_layouts.lua
199200
```
200201

201202
```bash

‎tests/checksum_test.lua‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
-- See the License for the specific language governing permissions and
1313
-- limitations under the License.
1414

15-
dofile("tests/support.lua")
15+
local test = require("vfox.test")
16+
test.load()
1617
local checksum = require("checksum")
1718

1819
local cases = 0

‎tests/github_mirror_test.lua‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
-- See the License for the specific language governing permissions and
1313
-- limitations under the License.
1414

15-
dofile("tests/support.lua")
15+
local test = require("vfox.test")
16+
test.load()
1617
local github_mirror = require("github_mirror")
1718

1819
-- The mirror comes from the environment: os.getenv answers for it from this

0 commit comments

Comments
 (0)