mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 16:01:01 +00:00
test(docker): fixture ClawHub plugin smoke
This commit is contained in:
@@ -611,6 +611,169 @@ CLAWHUB_PLUGIN_SPEC="${OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC:-clawhub:openclaw-now4r
|
||||
CLAWHUB_PLUGIN_ID="${OPENCLAW_PLUGINS_E2E_CLAWHUB_ID:-now4real}"
|
||||
export CLAWHUB_PLUGIN_SPEC CLAWHUB_PLUGIN_ID
|
||||
|
||||
start_clawhub_fixture_server() {
|
||||
local fixture_dir="$1"
|
||||
local server_log="$fixture_dir/clawhub-fixture.log"
|
||||
local server_port_file="$fixture_dir/clawhub-fixture-port"
|
||||
local server_pid_file="$fixture_dir/clawhub-fixture-pid"
|
||||
|
||||
node - <<'NODE' "$server_port_file" >"$server_log" 2>&1 &
|
||||
const crypto = require("node:crypto");
|
||||
const http = require("node:http");
|
||||
const path = require("node:path");
|
||||
const { createRequire } = require("node:module");
|
||||
|
||||
const portFile = process.argv[2];
|
||||
const requireFromApp = createRequire(path.join(process.cwd(), "package.json"));
|
||||
const JSZip = requireFromApp("jszip");
|
||||
const packageName = "openclaw-now4real";
|
||||
const pluginId = "now4real";
|
||||
const version = "0.1.2";
|
||||
|
||||
async function main() {
|
||||
const zip = new JSZip();
|
||||
zip.file(
|
||||
"package/package.json",
|
||||
`${JSON.stringify(
|
||||
{
|
||||
name: packageName,
|
||||
version,
|
||||
openclaw: { extensions: ["./index.js"] },
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
{ date: new Date(0) },
|
||||
);
|
||||
zip.file(
|
||||
"package/index.js",
|
||||
`module.exports = {
|
||||
id: "${pluginId}",
|
||||
name: "Now 4 Real",
|
||||
register(api) {
|
||||
api.registerGatewayMethod("now4real.ping", async () => ({ ok: true }));
|
||||
},
|
||||
};
|
||||
`,
|
||||
{ date: new Date(0) },
|
||||
);
|
||||
zip.file(
|
||||
"package/openclaw.plugin.json",
|
||||
`${JSON.stringify(
|
||||
{
|
||||
id: pluginId,
|
||||
configSchema: {
|
||||
type: "object",
|
||||
properties: {},
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
{ date: new Date(0) },
|
||||
);
|
||||
|
||||
const archive = await zip.generateAsync({ type: "nodebuffer", compression: "DEFLATE" });
|
||||
const sha256hash = crypto.createHash("sha256").update(archive).digest("hex");
|
||||
|
||||
const json = (response, value) => {
|
||||
response.writeHead(200, { "content-type": "application/json" });
|
||||
response.end(`${JSON.stringify(value)}\n`);
|
||||
};
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
const url = new URL(request.url, "http://127.0.0.1");
|
||||
if (request.method !== "GET") {
|
||||
response.writeHead(405);
|
||||
response.end("method not allowed");
|
||||
return;
|
||||
}
|
||||
if (url.pathname === `/api/v1/packages/${encodeURIComponent(packageName)}`) {
|
||||
json(response, {
|
||||
package: {
|
||||
name: packageName,
|
||||
displayName: "Now 4 Real",
|
||||
family: "code-plugin",
|
||||
channel: "official",
|
||||
isOfficial: true,
|
||||
runtimeId: pluginId,
|
||||
latestVersion: version,
|
||||
createdAt: 0,
|
||||
updatedAt: 0,
|
||||
compatibility: {
|
||||
pluginApiRange: ">=2026.4.11",
|
||||
minGatewayVersion: "2026.4.11",
|
||||
},
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (
|
||||
url.pathname === `/api/v1/packages/${encodeURIComponent(packageName)}/versions/${version}`
|
||||
) {
|
||||
json(response, {
|
||||
version: {
|
||||
version,
|
||||
createdAt: 0,
|
||||
changelog: "Fixture package for Docker plugin E2E.",
|
||||
sha256hash,
|
||||
compatibility: {
|
||||
pluginApiRange: ">=2026.4.11",
|
||||
minGatewayVersion: "2026.4.11",
|
||||
},
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (url.pathname === `/api/v1/packages/${encodeURIComponent(packageName)}/download`) {
|
||||
response.writeHead(200, {
|
||||
"content-type": "application/zip",
|
||||
"content-length": String(archive.length),
|
||||
});
|
||||
response.end(archive);
|
||||
return;
|
||||
}
|
||||
response.writeHead(404, { "content-type": "text/plain" });
|
||||
response.end(`not found: ${url.pathname}`);
|
||||
});
|
||||
|
||||
server.listen(0, "127.0.0.1", () => {
|
||||
require("node:fs").writeFileSync(portFile, String(server.address().port));
|
||||
});
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
NODE
|
||||
local server_pid="$!"
|
||||
echo "$server_pid" > "$server_pid_file"
|
||||
|
||||
for _ in $(seq 1 100); do
|
||||
if [[ -s "$server_port_file" ]]; then
|
||||
export OPENCLAW_CLAWHUB_URL="http://127.0.0.1:$(cat "$server_port_file")"
|
||||
trap 'if [[ -f "'"$server_pid_file"'" ]]; then kill "$(cat "'"$server_pid_file"'")" 2>/dev/null || true; fi' EXIT
|
||||
return 0
|
||||
fi
|
||||
if ! kill -0 "$server_pid" 2>/dev/null; then
|
||||
cat "$server_log"
|
||||
return 1
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
cat "$server_log"
|
||||
echo "Timed out waiting for ClawHub fixture server." >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
if [[ -z "${OPENCLAW_CLAWHUB_URL:-}" && -z "${CLAWHUB_URL:-}" ]]; then
|
||||
# Keep the release-path smoke hermetic; live ClawHub can rate-limit CI.
|
||||
clawhub_fixture_dir="$(mktemp -d "/tmp/openclaw-clawhub-fixture.XXXXXX")"
|
||||
start_clawhub_fixture_server "$clawhub_fixture_dir"
|
||||
fi
|
||||
|
||||
node - <<'NODE'
|
||||
const spec = process.env.CLAWHUB_PLUGIN_SPEC;
|
||||
if (!spec?.startsWith("clawhub:")) {
|
||||
|
||||
Reference in New Issue
Block a user