mirror of
https://github.com/denoland/deno.git
synced 2025-01-03 04:48:52 -05:00
tests: generate and upload wptreport.json (#10869)
These reports can be consumed by tools like `wptreport` or https://wpt.fyi. The old style report could be removed in a future PR when wpt.deno.land is updated.
This commit is contained in:
parent
5bd77f29e5
commit
f1deed41e7
5 changed files with 142 additions and 6 deletions
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
|
@ -177,8 +177,7 @@ jobs:
|
||||||
~/.cargo/registry/index
|
~/.cargo/registry/index
|
||||||
~/.cargo/registry/cache
|
~/.cargo/registry/cache
|
||||||
~/.cargo/git/db
|
~/.cargo/git/db
|
||||||
key:
|
key: a-cargo-home-${{ matrix.os }}-${{ hashFiles('Cargo.lock') }}
|
||||||
a-cargo-home-${{ matrix.os }}-${{ hashFiles('Cargo.lock') }}
|
|
||||||
|
|
||||||
# In main branch, always creates fresh cache
|
# In main branch, always creates fresh cache
|
||||||
- name: Cache build output (main)
|
- name: Cache build output (main)
|
||||||
|
@ -308,7 +307,7 @@ jobs:
|
||||||
if: startsWith(matrix.os, 'ubuntu') && matrix.kind == 'test' && matrix.profile == 'release'
|
if: startsWith(matrix.os, 'ubuntu') && matrix.kind == 'test' && matrix.profile == 'release'
|
||||||
run: |
|
run: |
|
||||||
deno run --unstable --allow-write --allow-read --allow-net --allow-env --allow-run ./tools/wpt.ts setup
|
deno run --unstable --allow-write --allow-read --allow-net --allow-env --allow-run ./tools/wpt.ts setup
|
||||||
deno run --unstable --allow-write --allow-read --allow-net --allow-env --allow-run ./tools/wpt.ts run --quiet --release --json=wpt.json
|
deno run --unstable --allow-write --allow-read --allow-net --allow-env --allow-run ./tools/wpt.ts run --quiet --release --json=wpt.json --wptreport=wptreport.json
|
||||||
|
|
||||||
- name: Upload wpt results to dl.deno.land
|
- name: Upload wpt results to dl.deno.land
|
||||||
if: |
|
if: |
|
||||||
|
@ -319,6 +318,7 @@ jobs:
|
||||||
github.ref == 'refs/heads/main'
|
github.ref == 'refs/heads/main'
|
||||||
run: |
|
run: |
|
||||||
gsutil cp ./wpt.json gs://dl.deno.land/wpt/$(git rev-parse HEAD).json
|
gsutil cp ./wpt.json gs://dl.deno.land/wpt/$(git rev-parse HEAD).json
|
||||||
|
gsutil cp ./wptreport.json gs://dl.deno.land/wpt/$(git rev-parse HEAD)-wptreport.json
|
||||||
echo $(git rev-parse HEAD) > wpt-latest.txt
|
echo $(git rev-parse HEAD) > wpt-latest.txt
|
||||||
gsutil cp wpt-latest.txt gs://dl.deno.land/wpt-latest.txt
|
gsutil cp wpt-latest.txt gs://dl.deno.land/wpt-latest.txt
|
||||||
|
|
||||||
|
@ -407,4 +407,3 @@ jobs:
|
||||||
rm -rf target/*/examples/
|
rm -rf target/*/examples/
|
||||||
rm -rf target/*/gn_out/
|
rm -rf target/*/gn_out/
|
||||||
rm -rf target/*/*.zip
|
rm -rf target/*/*.zip
|
||||||
|
|
||||||
|
|
60
tools/wpt.ts
60
tools/wpt.ts
|
@ -15,6 +15,7 @@ import {
|
||||||
cargoBuild,
|
cargoBuild,
|
||||||
checkPy3Available,
|
checkPy3Available,
|
||||||
Expectation,
|
Expectation,
|
||||||
|
generateRunInfo,
|
||||||
getExpectation,
|
getExpectation,
|
||||||
getExpectFailForCase,
|
getExpectFailForCase,
|
||||||
getManifest,
|
getManifest,
|
||||||
|
@ -26,6 +27,7 @@ import {
|
||||||
rest,
|
rest,
|
||||||
runPy,
|
runPy,
|
||||||
updateManifest,
|
updateManifest,
|
||||||
|
wptreport,
|
||||||
} from "./wpt/utils.ts";
|
} from "./wpt/utils.ts";
|
||||||
import {
|
import {
|
||||||
blue,
|
blue,
|
||||||
|
@ -148,6 +150,7 @@ interface TestToRun {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
|
const startTime = new Date().getTime();
|
||||||
assert(Array.isArray(rest), "filter must be array");
|
assert(Array.isArray(rest), "filter must be array");
|
||||||
const expectation = getExpectation();
|
const expectation = getExpectation();
|
||||||
const tests = discoverTestsToRun(
|
const tests = discoverTestsToRun(
|
||||||
|
@ -173,6 +176,7 @@ async function run() {
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
});
|
});
|
||||||
|
const endTime = new Date().getTime();
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
const minifiedResults = [];
|
const minifiedResults = [];
|
||||||
|
@ -191,10 +195,66 @@ async function run() {
|
||||||
}
|
}
|
||||||
await Deno.writeTextFile(json, JSON.stringify(minifiedResults));
|
await Deno.writeTextFile(json, JSON.stringify(minifiedResults));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wptreport) {
|
||||||
|
const report = await generateWptreport(results, startTime, endTime);
|
||||||
|
await Deno.writeTextFile(wptreport, JSON.stringify(report));
|
||||||
|
}
|
||||||
|
|
||||||
const code = reportFinal(results);
|
const code = reportFinal(results);
|
||||||
Deno.exit(code);
|
Deno.exit(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function generateWptreport(
|
||||||
|
results: { test: TestToRun; result: TestResult }[],
|
||||||
|
startTime: number,
|
||||||
|
endTime: number,
|
||||||
|
) {
|
||||||
|
const runInfo = await generateRunInfo();
|
||||||
|
const reportResults = [];
|
||||||
|
for (const { test, result } of results) {
|
||||||
|
const status = result.status !== 0
|
||||||
|
? "CRASH"
|
||||||
|
: result.harnessStatus?.status === 0
|
||||||
|
? "OK"
|
||||||
|
: "ERROR";
|
||||||
|
const reportResult = {
|
||||||
|
test: test.url.pathname + test.url.search + test.url.hash,
|
||||||
|
subtests: result.cases.map((case_) => {
|
||||||
|
let expected = undefined;
|
||||||
|
if (!case_.passed) {
|
||||||
|
if (typeof test.expectation === "boolean") {
|
||||||
|
expected = test.expectation ? "PASS" : "FAIL";
|
||||||
|
} else {
|
||||||
|
expected = test.expectation.includes(case_.name) ? "FAIL" : "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: case_.name,
|
||||||
|
status: case_.passed ? "PASS" : "FAIL",
|
||||||
|
message: case_.message,
|
||||||
|
expected,
|
||||||
|
known_intermittent: [],
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
status,
|
||||||
|
message: result.harnessStatus?.message ??
|
||||||
|
(result.stderr.trim() || null),
|
||||||
|
duration: result.duration,
|
||||||
|
expected: status === "OK" ? undefined : "OK",
|
||||||
|
"known_intermittent": [],
|
||||||
|
};
|
||||||
|
reportResults.push(reportResult);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
"run_info": runInfo,
|
||||||
|
"time_start": startTime,
|
||||||
|
"time_end": endTime,
|
||||||
|
"results": reportResults,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Check that all expectations in the expectations file have a test that will be
|
// Check that all expectations in the expectations file have a test that will be
|
||||||
// run.
|
// run.
|
||||||
function assertAllExpectationsHaveTests(
|
function assertAllExpectationsHaveTests(
|
||||||
|
|
|
@ -47,10 +47,18 @@ export async function runWithTestUtil<T>(
|
||||||
|
|
||||||
export interface TestResult {
|
export interface TestResult {
|
||||||
cases: TestCaseResult[];
|
cases: TestCaseResult[];
|
||||||
|
harnessStatus: TestHarnessStatus | null;
|
||||||
|
duration: number;
|
||||||
status: number;
|
status: number;
|
||||||
stderr: string;
|
stderr: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TestHarnessStatus {
|
||||||
|
status: number;
|
||||||
|
message: string | null;
|
||||||
|
stack: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface TestCaseResult {
|
export interface TestCaseResult {
|
||||||
name: string;
|
name: string;
|
||||||
passed: boolean;
|
passed: boolean;
|
||||||
|
@ -71,6 +79,8 @@ export async function runSingleTest(
|
||||||
});
|
});
|
||||||
await Deno.writeTextFile(tempFile, bundle);
|
await Deno.writeTextFile(tempFile, bundle);
|
||||||
|
|
||||||
|
const startTime = new Date().getTime();
|
||||||
|
|
||||||
const proc = Deno.run({
|
const proc = Deno.run({
|
||||||
cmd: [
|
cmd: [
|
||||||
join(ROOT_PATH, `./target/${release ? "release" : "debug"}/deno`),
|
join(ROOT_PATH, `./target/${release ? "release" : "debug"}/deno`),
|
||||||
|
@ -94,6 +104,8 @@ export async function runSingleTest(
|
||||||
const cases = [];
|
const cases = [];
|
||||||
let stderr = "";
|
let stderr = "";
|
||||||
|
|
||||||
|
let harnessStatus = null;
|
||||||
|
|
||||||
const lines = readLines(proc.stderr);
|
const lines = readLines(proc.stderr);
|
||||||
for await (const line of lines) {
|
for await (const line of lines) {
|
||||||
if (line.startsWith("{")) {
|
if (line.startsWith("{")) {
|
||||||
|
@ -101,15 +113,21 @@ export async function runSingleTest(
|
||||||
const result = { ...data, passed: data.status == 0 };
|
const result = { ...data, passed: data.status == 0 };
|
||||||
cases.push(result);
|
cases.push(result);
|
||||||
reporter(result);
|
reporter(result);
|
||||||
|
} else if (line.startsWith("#$#$#{")) {
|
||||||
|
harnessStatus = JSON.parse(line.slice(5));
|
||||||
} else {
|
} else {
|
||||||
stderr += line + "\n";
|
stderr += line + "\n";
|
||||||
console.error(stderr);
|
console.error(stderr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const duration = new Date().getTime() - startTime;
|
||||||
|
|
||||||
const { code } = await proc.status();
|
const { code } = await proc.status();
|
||||||
return {
|
return {
|
||||||
status: code,
|
status: code,
|
||||||
|
harnessStatus,
|
||||||
|
duration,
|
||||||
cases,
|
cases,
|
||||||
stderr,
|
stderr,
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,13 @@ window.add_result_callback(({ message, name, stack, status }) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.add_completion_callback((_tests, _harnessStatus) => {
|
window.add_completion_callback((_tests, harnessStatus) => {
|
||||||
|
const data = new TextEncoder().encode(
|
||||||
|
`#$#$#${JSON.stringify(harnessStatus)}\n`,
|
||||||
|
);
|
||||||
|
let bytesWritten = 0;
|
||||||
|
while (bytesWritten < data.byteLength) {
|
||||||
|
bytesWritten += Deno.stderr.writeSync(data.subarray(bytesWritten));
|
||||||
|
}
|
||||||
Deno.exit(0);
|
Deno.exit(0);
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { join, ROOT_PATH } from "../util.js";
|
||||||
|
|
||||||
export const {
|
export const {
|
||||||
json,
|
json,
|
||||||
|
wptreport,
|
||||||
quiet,
|
quiet,
|
||||||
release,
|
release,
|
||||||
rebuild,
|
rebuild,
|
||||||
|
@ -14,7 +15,7 @@ export const {
|
||||||
} = parse(Deno.args, {
|
} = parse(Deno.args, {
|
||||||
"--": true,
|
"--": true,
|
||||||
boolean: ["quiet", "release", "no-interactive"],
|
boolean: ["quiet", "release", "no-interactive"],
|
||||||
string: ["json"],
|
string: ["json", "wptreport"],
|
||||||
});
|
});
|
||||||
|
|
||||||
/// PAGE ROOT
|
/// PAGE ROOT
|
||||||
|
@ -145,3 +146,54 @@ export async function cargoBuild() {
|
||||||
proc.close();
|
proc.close();
|
||||||
assert(status.success, "cargo build failed");
|
assert(status.success, "cargo build failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// WPTREPORT
|
||||||
|
|
||||||
|
export async function generateRunInfo(): Promise<unknown> {
|
||||||
|
const oses = {
|
||||||
|
"windows": "win",
|
||||||
|
"darwin": "mac",
|
||||||
|
"linux": "linux",
|
||||||
|
};
|
||||||
|
const proc = Deno.run({
|
||||||
|
cmd: ["git", "rev-parse", "HEAD"],
|
||||||
|
cwd: join(ROOT_PATH, "test_util", "wpt"),
|
||||||
|
stdout: "piped",
|
||||||
|
});
|
||||||
|
await proc.status();
|
||||||
|
const revision = (new TextDecoder().decode(await proc.output())).trim();
|
||||||
|
proc.close();
|
||||||
|
const proc2 = Deno.run({
|
||||||
|
cmd: [
|
||||||
|
join(ROOT_PATH, `./target/${release ? "release" : "debug"}/deno`),
|
||||||
|
"eval",
|
||||||
|
"console.log(JSON.stringify(Deno.version))",
|
||||||
|
],
|
||||||
|
cwd: join(ROOT_PATH, "test_util", "wpt"),
|
||||||
|
stdout: "piped",
|
||||||
|
});
|
||||||
|
await proc2.status();
|
||||||
|
const version = JSON.parse(new TextDecoder().decode(await proc2.output()));
|
||||||
|
proc2.close();
|
||||||
|
const runInfo = {
|
||||||
|
"os": oses[Deno.build.os],
|
||||||
|
"processor": Deno.build.arch,
|
||||||
|
"version": "unknown",
|
||||||
|
"os_version": "unknown",
|
||||||
|
"bits": 64,
|
||||||
|
"has_sandbox": true,
|
||||||
|
"webrender": false,
|
||||||
|
"automation": false,
|
||||||
|
"linux_distro": "unknown",
|
||||||
|
"revision": revision,
|
||||||
|
"python_version": 3,
|
||||||
|
"product": "deno",
|
||||||
|
"debug": false,
|
||||||
|
"browser_version": version.deno,
|
||||||
|
"browser_channel": version.deno.includes("+") ? "canary" : "stable",
|
||||||
|
"verify": false,
|
||||||
|
"wasm": false,
|
||||||
|
"headless": true,
|
||||||
|
};
|
||||||
|
return runInfo;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue