diff --git a/CHANGELOG.md b/CHANGELOG.md index 38c9f568..4db9fb95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,15 @@ ### Added +- **`openkal` 0.16.0 及随之移动的七个包。** 规范新增 `kal_task_start_sized`(栈大小的下限, + 给不出时为 `kal_err_no_memory`)与 `KAL_TERM_PASS_INPUT`(环境不改写所输入的字节), + 并补述关闭目录即结束其未读完的枚举。`openkal-linux` 0.17.0、`openkal-macos` 0.14.0、 + `openkal-windows` 0.12.0、`openkal-emscripten` 0.5.0 实现三者;`openkal-opensbi` 0.8.3 + 只移动规范的锁定版本;`openkal-musl` 0.21.0 让线程得到所请求的栈并在 raw 模式下区分 + 回车与 Ctrl+J;`openkal-llvm-runtime` 0.15.5 移动 C 库的锁定版本。GLOBAL 为上游 tag 归档, + CN 为逐字节相同的 gitcode 资源,均按记录的 sha256 核对。 + 新增两个测试成员:`tests/examples/openkal`(规范在三平台、各实现在自身平台,以及新声明的 C + 层行为)与 `tests/examples/openkal-musl`(三份报告的原始程序,Linux)。 - **`compat.httplib` 0.62.0。** 在 `0.53.1` 之外新增版本键(旧键保留)。仍是纯头文件 Form B: 归档根目录仍只有一份 `httplib.h`(747,115 → 846,648 字节,增量是 SSE 客户端、WebSocket 辅助与加固,全部落在头内,不引入 define、源文件或链接依赖),描述符的内联构建无需改动。 @@ -182,6 +191,12 @@ ### Changed +- **候选门只在消费者构建候选包的平台上调度它。** `tests/autoupdate/ci.py` 的 + `member_platforms` 读取消费者清单:无条件依赖在三个平台调度;`cfg(os = ...)` 或 + `cfg(windows)` 下的依赖只在该平台调度;其余条件(环境、架构)不调度任何宿主作业,由包自身仓库 + 在目标上测量。mcpp 只锁定宿主解析到的包,向另一平台的 runner 要平台包的锁定证明必然失败; + `test_ci.py` 覆盖了这条规则。 + - **站点的 openkal 分面改为两个取值:`openkal-ecosystem` 与 `openkal-compat`。** 原先的 「openkal itself / runs on openkal / fails on openkal」是句子而不是名字。构成 openkal 的 包归入 `openkal-ecosystem`;测试项目在 openkal 依赖图中测得 `runs` 的包归入 diff --git a/mcpp.toml b/mcpp.toml index 9d9ea35e..a4ed5bb0 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -206,6 +206,8 @@ members = [ "tests/examples/quickjs-ng", "tests/examples/rapidcsv", "tests/examples/mcr", + "tests/examples/openkal", + "tests/examples/openkal-musl", ] # ── The index redirect, hoisted to the workspace root ─────────────────── diff --git a/pkgs/o/openkal-emscripten.lua b/pkgs/o/openkal-emscripten.lua index e1283052..bb0719b9 100644 --- a/pkgs/o/openkal-emscripten.lua +++ b/pkgs/o/openkal-emscripten.lua @@ -45,6 +45,13 @@ package = { xpm = { linux = { + ["0.5.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-emscripten/archive/refs/tags/0.5.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-emscripten/releases/download/0.5.0/openkal-emscripten-0.5.0.tar.gz", + }, + sha256 = "3f6ad34e6da89cd41899965a25083200b52eb2b36cc3ff138f82cb018638a217", + }, ["0.4.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-emscripten/archive/refs/tags/0.4.0.tar.gz", @@ -89,6 +96,13 @@ package = { }, }, macosx = { + ["0.5.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-emscripten/archive/refs/tags/0.5.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-emscripten/releases/download/0.5.0/openkal-emscripten-0.5.0.tar.gz", + }, + sha256 = "3f6ad34e6da89cd41899965a25083200b52eb2b36cc3ff138f82cb018638a217", + }, ["0.4.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-emscripten/archive/refs/tags/0.4.0.tar.gz", @@ -133,6 +147,13 @@ package = { }, }, windows = { + ["0.5.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-emscripten/archive/refs/tags/0.5.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-emscripten/releases/download/0.5.0/openkal-emscripten-0.5.0.tar.gz", + }, + sha256 = "3f6ad34e6da89cd41899965a25083200b52eb2b36cc3ff138f82cb018638a217", + }, ["0.4.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-emscripten/archive/refs/tags/0.4.0.tar.gz", diff --git a/pkgs/o/openkal-linux.lua b/pkgs/o/openkal-linux.lua index 860171a6..bdefb0c1 100644 --- a/pkgs/o/openkal-linux.lua +++ b/pkgs/o/openkal-linux.lua @@ -19,6 +19,13 @@ package = { xpm = { linux = { + ["0.17.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-linux/archive/refs/tags/0.17.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-linux/releases/download/0.17.0/openkal-linux-0.17.0.tar.gz", + }, + sha256 = "fc815721f0cb4fddcc708cf7960fe1d06f40d2c9541eeaaf3858bb9f53fadbe9", + }, ["0.16.1"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-linux/archive/refs/tags/0.16.1.tar.gz", @@ -147,6 +154,13 @@ package = { }, }, macosx = { + ["0.17.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-linux/archive/refs/tags/0.17.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-linux/releases/download/0.17.0/openkal-linux-0.17.0.tar.gz", + }, + sha256 = "fc815721f0cb4fddcc708cf7960fe1d06f40d2c9541eeaaf3858bb9f53fadbe9", + }, ["0.16.1"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-linux/archive/refs/tags/0.16.1.tar.gz", @@ -275,6 +289,13 @@ package = { }, }, windows = { + ["0.17.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-linux/archive/refs/tags/0.17.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-linux/releases/download/0.17.0/openkal-linux-0.17.0.tar.gz", + }, + sha256 = "fc815721f0cb4fddcc708cf7960fe1d06f40d2c9541eeaaf3858bb9f53fadbe9", + }, ["0.16.1"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-linux/archive/refs/tags/0.16.1.tar.gz", diff --git a/pkgs/o/openkal-llvm-runtime.lua b/pkgs/o/openkal-llvm-runtime.lua index f9fa2de9..970c9b3a 100644 --- a/pkgs/o/openkal-llvm-runtime.lua +++ b/pkgs/o/openkal-llvm-runtime.lua @@ -75,6 +75,13 @@ package = { xpm = { linux = { + ["0.15.5"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-llvm-runtime/archive/refs/tags/0.15.5.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-llvm-runtime/releases/download/0.15.5/openkal-llvm-runtime-0.15.5.tar.gz", + }, + sha256 = "22adf246d2a0cbf2083d09d88329c475f6c1976ea69d0d6cc0391b129fde12ae", + }, ["0.15.4"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-llvm-runtime/archive/refs/tags/0.15.4.tar.gz", @@ -287,6 +294,13 @@ package = { }, }, macosx = { + ["0.15.5"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-llvm-runtime/archive/refs/tags/0.15.5.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-llvm-runtime/releases/download/0.15.5/openkal-llvm-runtime-0.15.5.tar.gz", + }, + sha256 = "22adf246d2a0cbf2083d09d88329c475f6c1976ea69d0d6cc0391b129fde12ae", + }, ["0.15.4"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-llvm-runtime/archive/refs/tags/0.15.4.tar.gz", @@ -499,6 +513,13 @@ package = { }, }, windows = { + ["0.15.5"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-llvm-runtime/archive/refs/tags/0.15.5.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-llvm-runtime/releases/download/0.15.5/openkal-llvm-runtime-0.15.5.tar.gz", + }, + sha256 = "22adf246d2a0cbf2083d09d88329c475f6c1976ea69d0d6cc0391b129fde12ae", + }, ["0.15.4"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-llvm-runtime/archive/refs/tags/0.15.4.tar.gz", diff --git a/pkgs/o/openkal-macos.lua b/pkgs/o/openkal-macos.lua index 52c81350..01d2da08 100644 --- a/pkgs/o/openkal-macos.lua +++ b/pkgs/o/openkal-macos.lua @@ -19,6 +19,13 @@ package = { xpm = { linux = { + ["0.14.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-macos/archive/refs/tags/0.14.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-macos/releases/download/0.14.0/openkal-macos-0.14.0.tar.gz", + }, + sha256 = "823fa17180c161831dbf4e68bb128738b955d6d4228b22c3bd75e0b826a31a9f", + }, ["0.13.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-macos/archive/refs/tags/0.13.0.tar.gz", @@ -147,6 +154,13 @@ package = { }, }, macosx = { + ["0.14.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-macos/archive/refs/tags/0.14.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-macos/releases/download/0.14.0/openkal-macos-0.14.0.tar.gz", + }, + sha256 = "823fa17180c161831dbf4e68bb128738b955d6d4228b22c3bd75e0b826a31a9f", + }, ["0.13.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-macos/archive/refs/tags/0.13.0.tar.gz", @@ -275,6 +289,13 @@ package = { }, }, windows = { + ["0.14.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-macos/archive/refs/tags/0.14.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-macos/releases/download/0.14.0/openkal-macos-0.14.0.tar.gz", + }, + sha256 = "823fa17180c161831dbf4e68bb128738b955d6d4228b22c3bd75e0b826a31a9f", + }, ["0.13.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-macos/archive/refs/tags/0.13.0.tar.gz", diff --git a/pkgs/o/openkal-musl.lua b/pkgs/o/openkal-musl.lua index 01b7e85f..6dc75fa7 100644 --- a/pkgs/o/openkal-musl.lua +++ b/pkgs/o/openkal-musl.lua @@ -64,6 +64,13 @@ package = { xpm = { linux = { + ["0.21.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-musl/archive/refs/tags/0.21.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-musl/releases/download/0.21.0/openkal-musl-0.21.0.tar.gz", + }, + sha256 = "98889c1fa7bbac05787e8c362ea79e4941c97aaa1ffca86a0ed7d88ff419545c", + }, ["0.20.1"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-musl/archive/refs/tags/0.20.1.tar.gz", @@ -290,6 +297,13 @@ package = { }, }, macosx = { + ["0.21.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-musl/archive/refs/tags/0.21.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-musl/releases/download/0.21.0/openkal-musl-0.21.0.tar.gz", + }, + sha256 = "98889c1fa7bbac05787e8c362ea79e4941c97aaa1ffca86a0ed7d88ff419545c", + }, ["0.20.1"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-musl/archive/refs/tags/0.20.1.tar.gz", @@ -516,6 +530,13 @@ package = { }, }, windows = { + ["0.21.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-musl/archive/refs/tags/0.21.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-musl/releases/download/0.21.0/openkal-musl-0.21.0.tar.gz", + }, + sha256 = "98889c1fa7bbac05787e8c362ea79e4941c97aaa1ffca86a0ed7d88ff419545c", + }, ["0.20.1"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-musl/archive/refs/tags/0.20.1.tar.gz", diff --git a/pkgs/o/openkal-opensbi.lua b/pkgs/o/openkal-opensbi.lua index accdb069..419f1363 100644 --- a/pkgs/o/openkal-opensbi.lua +++ b/pkgs/o/openkal-opensbi.lua @@ -20,6 +20,13 @@ package = { xpm = { linux = { + ["0.8.3"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-opensbi/archive/refs/tags/0.8.3.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-opensbi/releases/download/0.8.3/openkal-opensbi-0.8.3.tar.gz", + }, + sha256 = "d585a8e614b27e7cd992f4db53fba200440f164870e9f475f67e976ff090aae3", + }, ["0.8.2"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-opensbi/archive/refs/tags/0.8.2.tar.gz", @@ -120,6 +127,13 @@ package = { }, }, macosx = { + ["0.8.3"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-opensbi/archive/refs/tags/0.8.3.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-opensbi/releases/download/0.8.3/openkal-opensbi-0.8.3.tar.gz", + }, + sha256 = "d585a8e614b27e7cd992f4db53fba200440f164870e9f475f67e976ff090aae3", + }, ["0.8.2"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-opensbi/archive/refs/tags/0.8.2.tar.gz", @@ -220,6 +234,13 @@ package = { }, }, windows = { + ["0.8.3"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-opensbi/archive/refs/tags/0.8.3.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-opensbi/releases/download/0.8.3/openkal-opensbi-0.8.3.tar.gz", + }, + sha256 = "d585a8e614b27e7cd992f4db53fba200440f164870e9f475f67e976ff090aae3", + }, ["0.8.2"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-opensbi/archive/refs/tags/0.8.2.tar.gz", diff --git a/pkgs/o/openkal-windows.lua b/pkgs/o/openkal-windows.lua index e32e13e8..aee05089 100644 --- a/pkgs/o/openkal-windows.lua +++ b/pkgs/o/openkal-windows.lua @@ -21,6 +21,13 @@ package = { xpm = { linux = { + ["0.12.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-windows/archive/refs/tags/0.12.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-windows/releases/download/0.12.0/openkal-windows-0.12.0.tar.gz", + }, + sha256 = "5ba523c3c34a0fe2257716bab3ce5196b38b98468283e93cc90b26feb65f6d46", + }, ["0.11.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-windows/archive/refs/tags/0.11.0.tar.gz", @@ -170,6 +177,13 @@ package = { }, }, macosx = { + ["0.12.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-windows/archive/refs/tags/0.12.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-windows/releases/download/0.12.0/openkal-windows-0.12.0.tar.gz", + }, + sha256 = "5ba523c3c34a0fe2257716bab3ce5196b38b98468283e93cc90b26feb65f6d46", + }, ["0.11.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-windows/archive/refs/tags/0.11.0.tar.gz", @@ -319,6 +333,13 @@ package = { }, }, windows = { + ["0.12.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal-windows/archive/refs/tags/0.12.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal-windows/releases/download/0.12.0/openkal-windows-0.12.0.tar.gz", + }, + sha256 = "5ba523c3c34a0fe2257716bab3ce5196b38b98468283e93cc90b26feb65f6d46", + }, ["0.11.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal-windows/archive/refs/tags/0.11.0.tar.gz", diff --git a/pkgs/o/openkal.lua b/pkgs/o/openkal.lua index ac39fccd..b20717af 100644 --- a/pkgs/o/openkal.lua +++ b/pkgs/o/openkal.lua @@ -22,6 +22,13 @@ package = { xpm = { linux = { + ["0.16.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal/archive/refs/tags/0.16.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal/releases/download/0.16.0/openkal-0.16.0.tar.gz", + }, + sha256 = "24a349b4eb7cd3d916455a8700718d57ee7ecce5cc161800f4842dece414e034", + }, ["0.15.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal/archive/refs/tags/0.15.0.tar.gz", @@ -122,6 +129,13 @@ package = { }, }, macosx = { + ["0.16.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal/archive/refs/tags/0.16.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal/releases/download/0.16.0/openkal-0.16.0.tar.gz", + }, + sha256 = "24a349b4eb7cd3d916455a8700718d57ee7ecce5cc161800f4842dece414e034", + }, ["0.15.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal/archive/refs/tags/0.15.0.tar.gz", @@ -222,6 +236,13 @@ package = { }, }, windows = { + ["0.16.0"] = { + url = { + GLOBAL = "https://github.com/mcpplibs/openkal/archive/refs/tags/0.16.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/openkal/releases/download/0.16.0/openkal-0.16.0.tar.gz", + }, + sha256 = "24a349b4eb7cd3d916455a8700718d57ee7ecce5cc161800f4842dece414e034", + }, ["0.15.0"] = { url = { GLOBAL = "https://github.com/mcpplibs/openkal/archive/refs/tags/0.15.0.tar.gz", diff --git a/tests/autoupdate/ci.py b/tests/autoupdate/ci.py index 5ac9b733..a81c81cf 100644 --- a/tests/autoupdate/ci.py +++ b/tests/autoupdate/ci.py @@ -101,6 +101,38 @@ def direct_member(identity: str) -> str | None: return min(candidates, key=lambda value: (len(value), value)) +# The runner platforms, by the spelling a member's `cfg(os = ...)` uses. +_CFG_PLATFORMS = {"linux": "linux", "macos": "macosx", "windows": "windows"} + + +def member_platforms(member: str, identity: str) -> set[str]: + """The runner platforms on which `member` builds `identity`. + + A member that names the package unconditionally builds it everywhere. One + that names it under `[target.'cfg(...)']` builds it only where the condition + holds, and a lockfile proves a candidate only where it was built: mcpp locks + what the host resolves, so a platform package asked of another platform's + runner is a job that can only fail. A condition naming one operating system + (`os = "linux"`, `os = "macos"`, `windows`) selects that runner; any other + condition (an environment, an architecture, a family) selects none, because + no runner here builds for it and the package is measured by its own + repository on that target. + """ + namespace, name = identity.split(":", 1) + manifest = tomllib.loads((ROOT / "tests/examples" / member / "mcpp.toml").read_text(encoding="utf-8")) + platforms: set[str] = set() + if name in manifest.get("dependencies", {}).get(namespace, {}): + platforms |= set(_CFG_PLATFORMS.values()) + for condition, table in manifest.get("target", {}).items(): + if name not in table.get("dependencies", {}).get(namespace, {}): + continue + spelled = re.fullmatch(r'cfg\(\s*(?:os\s*=\s*"(\w+)"|(windows))\s*\)', condition.strip()) + if spelled: + platforms.add(_CFG_PLATFORMS.get(spelled.group(1) or spelled.group(2), "")) + platforms.discard("") + return platforms + + def matrix(plan: Path, output: Path, base: str): build_plan = json.loads(plan.read_text(encoding="utf-8")) # A normal bump PR already contains its candidate, so discovery says up-to-date. @@ -136,7 +168,13 @@ def matrix(plan: Path, output: Path, base: str): member = direct_member(record["id"]) if member is None and record["id"] not in ("compat:hiredis", "compat:libuv"): raise RuntimeError(f"no candidate consumer: {record['id']}") + applicable = member_platforms(member, record["id"]) if member else None + if applicable is not None and not applicable: + print(f"{record['id']}: {member} names it only for a target no runner builds; " + "measured by its own repository on that target") for platform in [asset["platform"] for asset in record["assets"]]: + if applicable is not None and platform not in applicable: + continue rows = { "linux": ("ubuntu-latest", "linux-x86_64", "tar.gz"), "macosx": ("macos-15", "macosx-arm64", "tar.gz"), diff --git a/tests/autoupdate/test_ci.py b/tests/autoupdate/test_ci.py index 0b8da9e2..c837f69b 100644 --- a/tests/autoupdate/test_ci.py +++ b/tests/autoupdate/test_ci.py @@ -100,3 +100,42 @@ def test_revision_allows_packaging_fix_but_not_resource_drift(self): 'sha256 = "' + "a" * 64 + '",\n revision = 0,')) with self.assertRaisesRegex(RuntimeError, "revision decreased"): ci.audit("HEAD", root / "coverage.json") + + +class MemberPlatformTests(unittest.TestCase): + """A candidate is asked of the runners its consumer builds it on, and of no other.""" + + def member(self, root, text): + member = root / "tests/examples/probe" + member.mkdir(parents=True) + (member / "mcpp.toml").write_text(text, encoding="utf-8") + + def test_conditions_select_runners(self): + with tempfile.TemporaryDirectory() as directory: + root = Path(directory) + self.member(root, """[package] +name = "probe" +version = "0.1.0" + +[dependencies.acme] +spec = "1.0.0" + +[target.'cfg(os = "linux")'.dependencies.acme] +on-linux = "1.0.0" + +[target.'cfg(os = "macos")'.dependencies.acme] +on-macos = "1.0.0" + +[target.'cfg(windows)'.dependencies.acme] +on-windows = "1.0.0" + +[target.'cfg(all(os = "linux", env = "musl"))'.dependencies.acme] +on-musl = "1.0.0" +""") + with patch.object(ci, "ROOT", root): + self.assertEqual(ci.member_platforms("probe", "acme:spec"), {"linux", "macosx", "windows"}) + self.assertEqual(ci.member_platforms("probe", "acme:on-linux"), {"linux"}) + self.assertEqual(ci.member_platforms("probe", "acme:on-macos"), {"macosx"}) + self.assertEqual(ci.member_platforms("probe", "acme:on-windows"), {"windows"}) + self.assertEqual(ci.member_platforms("probe", "acme:on-musl"), set()) + self.assertEqual(ci.member_platforms("probe", "other:spec"), set()) diff --git a/tests/examples/openkal-musl/mcpp.toml b/tests/examples/openkal-musl/mcpp.toml new file mode 100644 index 00000000..7969a47f --- /dev/null +++ b/tests/examples/openkal-musl/mcpp.toml @@ -0,0 +1,22 @@ +# openkal-musl test project: a C program whose C library is musl redirected +# onto openkal, running the programs three reports were written with +# (mcpplibs/openkal-linux#34, mcpplibs/openkal-musl#48, the stack and the +# supplied stack). Linux only: the port's other systems are measured by its +# own repository, and the candidate gate asks this member nothing elsewhere. +[package] +name = "openkal-musl-tests" +version = "0.1.0" + +[target.'cfg(os = "linux")'.dependencies.mcpplibs] +openkal-musl = "0.21.0" + +[target.'cfg(os = "linux")'.build] +cxxflags = ["-DHAVE_OPENKAL_MUSL=1"] + +# The test is C++ because the test runner discovers C++; what it exercises is +# C, and the C++ runtime is the host's, as in the port's own examples/threads-cxx. +[build] +cxx_runtime = "host-coupled" + +[indices] +mcpplibs = { path = "../../.." } diff --git a/tests/examples/openkal-musl/tests/reports.cpp b/tests/examples/openkal-musl/tests/reports.cpp new file mode 100644 index 00000000..d953b0ea --- /dev/null +++ b/tests/examples/openkal-musl/tests/reports.cpp @@ -0,0 +1,50 @@ +/* The reporters' programs, above openkal-musl. Elsewhere this compiles to a + * main() that reports nothing, because the member names the port for Linux + * alone. */ +#ifndef HAVE_OPENKAL_MUSL +int main(void) { return 0; } +#else +#define _GNU_SOURCE 1 +#include +#include +#include +#include +#include +#include +#include + +static int failures = 0; + +static void check(int ok, const char* what) { printf("%s %s\n", ok ? " ok " : " FAIL", what); if (!ok) failures++; } + +static int open_descriptors(void) { + DIR* d = opendir("/proc/self/fd"); if (!d) return -1; + int n = 0; while (readdir(d)) n++; closedir(d); return n; +} + +static long recurse(long n) { volatile char pad[1000]; pad[0] = 1; return n ? recurse(n - 1) + pad[0] : 0; } +static void* body(void* arg) { *(long*)arg = recurse(*(long*)arg); return nullptr; } + +int main(void) { + char name[64]; + mkdir("okm.d", 0755); + for (int i = 0; i < 300; i++) { snprintf(name, sizeof name, "okm.d/e%03d", i); close(open(name, O_WRONLY | O_CREAT, 0644)); } + const int before = open_descriptors(); + for (int i = 0; i < 64; i++) { DIR* d = opendir("okm.d"); if (d) { readdir(d); closedir(d); } } + const int after = open_descriptors(); + for (int i = 0; i < 300; i++) { snprintf(name, sizeof name, "okm.d/e%03d", i); unlink(name); } + rmdir("okm.d"); + printf("descriptors before=%d after=%d\n", before, after); + if (before >= 0) check(before == after, "a directory closed early leaves nothing open"); + + pthread_attr_t attr; pthread_t t; long depth = 3900; + pthread_attr_init(&attr); + pthread_attr_setstacksize(&attr, 4u << 20); + check(pthread_create(&t, &attr, body, &depth) == 0 && pthread_join(t, 0) == 0 && depth == 3900, + "a thread that asked for 4 MiB recursed 3900 levels of about 1 KiB"); + static char region[1 << 20]; + pthread_attr_setstack(&attr, region, sizeof region); + check(pthread_create(&t, &attr, body, &depth) == EINVAL, "a stack the caller supplies is refused"); + return failures != 0; +} +#endif diff --git a/tests/examples/openkal/mcpp.toml b/tests/examples/openkal/mcpp.toml new file mode 100644 index 00000000..b88bc597 --- /dev/null +++ b/tests/examples/openkal/mcpp.toml @@ -0,0 +1,45 @@ +# openkal test project: the specification, the implementation for each runner, +# and the packages that are consumed only for a target no runner here builds. +# +# What it protects. The specification resolves on every runner and its +# declarations compile there; each implementation resolves, links and answers +# on its own operating system; and the C-level behaviour of the round that +# added the newest declarations holds on all three (tests/kal.cpp). A candidate +# for one of these packages is built only where this manifest names it +# (tests/autoupdate/ci.py, `member_platforms`): an implementation for another +# system is not in the host's lock, so asking that runner would prove nothing. +# +# The last three entries are named under conditions no runner here builds for +# --- a musl environment, WebAssembly, a 64-bit RISC-V machine --- so the +# candidate gate schedules none of them, and their own repositories measure +# them on their targets. +[package] +name = "openkal-tests" +version = "0.1.0" + +[dependencies.mcpplibs] +openkal = "0.16.0" + +[target.'cfg(os = "linux")'.dependencies.mcpplibs] +openkal-linux = "0.17.0" + +[target.'cfg(os = "macos")'.dependencies.mcpplibs] +openkal-macos = "0.14.0" + +[target.'cfg(windows)'.dependencies.mcpplibs] +openkal-windows = "0.12.0" + +[target.'cfg(all(os = "linux", env = "musl"))'.dependencies.mcpplibs] +openkal-llvm-runtime = "0.15.5" + +[target.'cfg(arch = "wasm32")'.dependencies.mcpplibs] +openkal-emscripten = "0.5.0" + +[target.'cfg(arch = "riscv64")'.dependencies.mcpplibs] +openkal-opensbi = "0.8.3" + +# This member names mcpplibs packages, which the workspace root's single +# redirect does not carry, so it states its own (mcpp.toml at the root says why +# a member that needs another namespace declares its own table). +[indices] +mcpplibs = { path = "../../.." } diff --git a/tests/examples/openkal/tests/kal.cpp b/tests/examples/openkal/tests/kal.cpp new file mode 100644 index 00000000..048105fd --- /dev/null +++ b/tests/examples/openkal/tests/kal.cpp @@ -0,0 +1,65 @@ +// The C surface of openkal through the implementation for this system. +// +// One observation per declaration the newest round added, in the terms a +// caller relies on: a context started with a least stack size is told at least +// that size and has the room; a closed directory's enumeration is refused; the +// input position is not an error to ask for. The terminal is not observed here, +// because a test run has none; the implementations observe it on a terminal +// they make. +#include +#include +#include +#include + +namespace { +int failures = 0; +void check(bool ok, const char* what) { + if (ok) return; + ++failures; + kal_uintptr n = 0; while (what[n]) ++n; + kal_stream_write(kal_stderr(), "FAIL: ", 6); + kal_stream_write(kal_stderr(), what, n); + kal_stream_write(kal_stderr(), "\n", 1); +} + +long recurse(long n); +long (*volatile g_recurse)(long) = recurse; +long recurse(long n) { volatile char pad[1000]; pad[0] = static_cast(n); return n ? g_recurse(n - 1) + pad[0] : 0; } + +struct probe { kal_uintptr told; volatile int done; }; +void room(void* p) { + auto* q = static_cast(p); + void* base = nullptr; kal_uintptr size = 0; + if (kal_task_stack(&base, &size) == kal_ok) q->told = size; + g_recurse(3 * 1024); + q->done = 1; +} +} + +int main() { + check(KAL_VERSION_MINOR >= 16u || KAL_VERSION_MAJOR > 0u, "the declarations are openkal 0.16 or later"); + check(kal_version() >= KAL_VERSION, "the implementation is at least as new as the declarations"); + + probe q{0, 0}; + kal_task t{}; + check(kal_task_start_sized(room, &q, 4u << 20, &t) == kal_ok, "a context with a least stack size starts"); + kal_task_join(t); + check(q.told >= (4u << 20), "it is told at least the size asked for"); + check(q.done == 1, "it has the room"); + + kal_dir root{}; + if (kal_fs_preopen_count() > 0 && kal_fs_preopen(0, &root, nullptr, 0, nullptr) == kal_ok) { + kal_fs_mkdir(root, "okt.d", 5); + kal_dir d{}; kal_uintptr it = 0; + if (kal_fs_open_dir(root, "okt.d", 5, &d) == kal_ok && kal_fs_list_begin(d, &it) == kal_ok) { + kal_fs_close_dir(d); + char name[64]; kal_uintptr len = 0; int kind = 0; + check(kal_fs_list_next(d, &it, name, sizeof name, &len, &kind) == kal_err_invalid, + "an enumeration of a closed directory is refused"); + } + kal_fs_remove(root, "okt.d", 5); + } + + if (failures == 0) kal_stream_write(kal_stdout(), "openkal: held\n", 14); + return failures == 0 ? 0 : 1; +}