Skip to content

Commit 33bdf3a

Browse files
committed
Merge branch 'main' into 2025-10-14_simpler_startup
2 parents cea65b8 + 24b1911 commit 33bdf3a

13 files changed

Lines changed: 343 additions & 75 deletions

File tree

.github/workflows/test.yml

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ on:
1010
workflow_dispatch:
1111

1212
jobs:
13-
build:
14-
name: Build
13+
test:
14+
name: Test
1515
runs-on: macos-latest
1616
env:
1717
GITHUB_ACTIONS_OUTPUT: ""
@@ -49,3 +49,30 @@ jobs:
4949
run: |
5050
echo "Running in $BROWSER"
5151
npm run test:${{ matrix.browser }}
52+
53+
build:
54+
name: Build
55+
runs-on: ubuntu-latest
56+
steps:
57+
- name: Checkout Branch
58+
uses: actions/checkout@v4
59+
with:
60+
fetch-depth: ${{ github.event_name == 'pull_request' && 2 || 0 }}
61+
62+
- name: Setup Node
63+
uses: actions/setup-node@v4
64+
with:
65+
node-version-file: package.json
66+
cache: npm
67+
68+
- name: Install Node Packages
69+
run: npm ci
70+
71+
- name: Run Build
72+
run: |
73+
if ${{ github.event_name == 'pull_request' }}; then
74+
npm run test:build -- --diff="HEAD^...HEAD"
75+
else
76+
npm run test:build -- --diff="${{ github.event.before }}...${{ github.event.after }}"
77+
fi
78+

JetStream.css

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,64 @@ body {
6969
height: 100%;
7070
}
7171

72+
table {
73+
border-spacing: 0;
74+
}
75+
76+
body.nonDefaultParams {
77+
filter: hue-rotate(152deg);
78+
}
79+
80+
.nonDefaultParams .summary {
81+
display: none;
82+
}
83+
84+
#non-default-params {
85+
display: none;
86+
text-align: center;
87+
88+
& h2 {
89+
text-align: center;
90+
}
91+
92+
& p {
93+
text-align: center;
94+
}
95+
}
96+
97+
.nonDefaultParams #non-default-params {
98+
display: block;
99+
}
100+
101+
#non-standard-params-table {
102+
border-collapse: collapse;
103+
text-align: left;
104+
display: inline-block;
105+
margin-top: var(--gap);
106+
}
107+
108+
#non-standard-params-table tr {
109+
padding: 2px;
110+
}
111+
112+
#non-standard-params-table thead th {
113+
border-bottom: 1px solid var(--foreground);
114+
}
115+
116+
#non-standard-params-table tbody td {
117+
font-weight: normal;
118+
text-align: left;
119+
}
120+
121+
#non-standard-params-table thead th,
122+
#non-standard-params-table tbody td {
123+
padding: 0.1em 0.3em;
124+
}
125+
#non-standard-params-table tbody td:nth-child(2) {
126+
color: var(--highlight);
127+
}
128+
129+
72130
.overflow-scroll {
73131
overflow-y: auto;
74132
}

JetStreamDriver.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,11 @@ class Driver {
302302
}
303303
}
304304

305-
const totalScore = geomeanScore(allScores);
306-
console.assert(totalScore > 0, `Invalid total score: ${totalScore}`);
305+
const overallScore = geomeanScore(allScores);
306+
console.assert(overallScore > 0, `Invalid total score: ${overallScore}`);
307307

308308
if (isInBrowser) {
309-
let summaryHtml = `<div class="score">${uiFriendlyScore(totalScore)}</div>
309+
let summaryHtml = `<div class="score">${uiFriendlyScore(overallScore)}</div>
310310
<label>Score</label>`;
311311
summaryHtml += `<div class="benchmark benchmark-done">`;
312312
for (let [category, scores] of categoryScores) {
@@ -328,20 +328,20 @@ class Driver {
328328
summaryElement.onclick = displayCategoryScores;
329329
statusElement.innerHTML = "";
330330
} else if (!JetStreamParams.dumpJSONResults) {
331-
console.log("Total:");
331+
console.log("Overall:");
332332
for (let [category, scores] of categoryScores) {
333333
console.log(
334-
shellFriendlyLabel(`Total ${category}-Score`),
334+
shellFriendlyLabel(`Overall ${category}-Score`),
335335
shellFriendlyScore(geomeanScore(scores)));
336336
}
337337
for (let [category, times] of categoryTimes) {
338338
console.log(
339-
shellFriendlyLabel(`Total ${category}-Time`),
339+
shellFriendlyLabel(`Overall ${category}-Time`),
340340
shellFriendlyDuration(geomeanScore(times)));
341341
}
342342
console.log("");
343-
console.log(shellFriendlyLabel("Total Score"), shellFriendlyScore(totalScore));
344-
console.log(shellFriendlyLabel("Total Time"), shellFriendlyDuration(totalTime));
343+
console.log(shellFriendlyLabel("Overall Score"), shellFriendlyScore(overallScore));
344+
console.log(shellFriendlyLabel("Overall Wall-Time"), shellFriendlyDuration(totalTime));
345345
console.log("");
346346
}
347347

@@ -833,8 +833,8 @@ class Benchmark {
833833

834834
allTimes() {
835835
const allTimes = this.subTimes();
836-
allTimes["Wall"] = this.wallTime;
837836
allTimes["Total"] = this.totalTime;
837+
allTimes["Wall"] = this.wallTime;
838838
return allTimes;
839839
}
840840

cli.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const CLI_PARAMS = {
4141
param: "dumpJSONResults",
4242
},
4343
"dump-test-list": {
44-
help: "Print test list instead of running.",
44+
help: "Print the selected test list instead of running.",
4545
param: "dumpTestList",
4646
},
4747
ramification: {

index.html

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@
3636
const isInBrowser = true;
3737
const isD8 = false;
3838
const isSpiderMonkey = false;
39-
globalThis.JetStreamParamsSource = new URLSearchParams(globalThis?.location?.search);
39+
if (globalThis?.location?.search) {
40+
globalThis.JetStreamParamsSource = new URLSearchParams(globalThis?.location?.search);
41+
}
4042
globalThis.allIsGood = true;
4143
window.onerror = function(e) {
4244
if (e == "Script error.") {
@@ -53,6 +55,9 @@
5355
if (JetStreamParams.startDelay !== undefined) {
5456
bodyClassList.remove("animate");
5557
}
58+
if (!JetStreamParams.isDefault) {
59+
showNonDefaultParams();
60+
}
5661
if (globalThis.allIsGood) {
5762
try {
5863
await JetStream.initialize();
@@ -72,6 +77,17 @@
7277
}
7378
}
7479

80+
function showNonDefaultParams() {
81+
document.body.classList.add("nonDefaultParams");
82+
const body = document.querySelector("#non-standard-params-table tbody");
83+
for (const [key, value] of Object.entries(JetStreamParams.nonDefaultParams)) {
84+
const defaultValue = DefaultJetStreamParams[key]
85+
const row = body.insertRow();
86+
row.insertCell().textContent = key;
87+
row.insertCell().textContent = JSON.stringify(value);
88+
row.insertCell().textContent = JSON.stringify(defaultValue);
89+
}
90+
}
7591
</script>
7692

7793
<script src="params.js"></script>
@@ -87,6 +103,23 @@ <h1 class="logo">
87103

88104
<main>
89105
<p class="summary">JetStream 3 is a JavaScript and WebAssembly benchmark suite focused on the most advanced web applications. It rewards browsers that start up quickly, execute code quickly, and run smoothly. For more information, read the <a href="in-depth.html">in-depth analysis</a>. Bigger scores are better.</p>
106+
<div id="non-default-params">
107+
<h2>Non-standard Parameters</h2>
108+
<p>
109+
JetStream ran with non-standard parameters.<br />
110+
The results are likely not comparable to default runs.
111+
</p>
112+
<table id="non-standard-params-table">
113+
<thead>
114+
<tr>
115+
<th>Param</th>
116+
<th>Value</th>
117+
<th>Default</th>
118+
</tr>
119+
</thead>
120+
<tbody></tbody>
121+
</table>
122+
</div>
90123
<p class="summary" id="mode-description"></p>
91124

92125
<div id="result-summary"></div>

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
"test:shell": "npm run test:prepare && npm run test:v8 && npm run test:jsc && npm run test:spidermonkey",
3232
"test:v8": "npm run test:prepare && node tests/run-shell.mjs --shell v8",
3333
"test:jsc": "npm run test:prepare && node tests/run-shell.mjs --shell jsc",
34-
"test:spidermonkey": "npm run test:prepare && node tests/run-shell.mjs --shell spidermonkey"
34+
"test:spidermonkey": "npm run test:prepare && node tests/run-shell.mjs --shell spidermonkey",
35+
"test:build": "npm run test:prepare && node tests/run-build.mjs"
3536
},
3637
"devDependencies": {
3738
"@actions/core": "^1.11.1",

params.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,9 @@ class Params {
140140
_parseBooleanParam(sourceParams, paramKey) {
141141
if (!sourceParams.has(paramKey))
142142
return DefaultJetStreamParams[paramKey];
143-
const value = sourceParams.get(paramKey).toLowerCase();
143+
const rawValue = sourceParams.get(paramKey);;
144144
sourceParams.delete(paramKey);
145+
const value = rawValue.toLowerCase();
145146
return !(value === "false" || value === "0");
146147
}
147148

@@ -170,9 +171,10 @@ class Params {
170171
get nonDefaultParams() {
171172
const diff = Object.create(null);
172173
for (const [key, value] of Object.entries(this)) {
173-
if (value !== DefaultJetStreamParams[key]) {
174-
diff[key] = value;
175-
}
174+
const defaultValue = DefaultJetStreamParams[key]
175+
if (value == defaultValue) continue;
176+
if (value?.length == 0 && defaultValue?.length == 0) continue;
177+
diff[key] = value;
176178
}
177179
return diff;
178180
}
@@ -183,6 +185,10 @@ let maybeCustomParams = DefaultJetStreamParams;
183185
if (globalThis?.JetStreamParamsSource) {
184186
try {
185187
maybeCustomParams = new Params(globalThis?.JetStreamParamsSource);
188+
// We might have parsed the same values again, do a poor-mans deep-equals:
189+
if (JSON.stringify(maybeCustomParams) === JSON.stringify(DefaultJetStreamParams)) {
190+
maybeCustomParams = DefaultJetStreamParams
191+
}
186192
} catch (e) {
187193
console.error("Invalid Params", e, "\nUsing defaults as fallback:", maybeCustomParams);
188194
}

tests/helper.mjs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@
2121
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2222
// THE POSSIBILITY OF SUCH DAMAGE.
2323

24-
import { styleText } from "node:util";
2524
import core from "@actions/core";
25+
import { spawn } from "child_process";
2626
import commandLineUsage from "command-line-usage";
27+
import { styleText } from "node:util";
2728

28-
export const GITHUB_ACTIONS_OUTPUT = "GITHUB_ACTIONS_OUTPUT" in process.env;
29+
export const GITHUB_ACTIONS_OUTPUT = ("GITHUB_ACTIONS_OUTPUT" in process.env) || ("GITHUB_EVENT_PATH" in process.env);
2930

3031
export function logInfo(...args) {
3132
const text = args.join(" ")
@@ -53,6 +54,16 @@ export function logError(...args) {
5354
}
5455
}
5556

57+
export function logCommand(...args) {
58+
const cmd = args.join(" ");
59+
if (GITHUB_ACTIONS_OUTPUT) {
60+
core.notice(styleText("blue", cmd));
61+
} else {
62+
console.log(styleText("blue", cmd));
63+
}
64+
}
65+
66+
5667
export async function logGroup(name, body) {
5768
if (GITHUB_ACTIONS_OUTPUT) {
5869
core.startGroup(name);
@@ -103,3 +114,49 @@ export async function runTest(label, testFunction) {
103114
}
104115
return true;
105116
}
117+
118+
119+
export async function sh(binary, ...args) {
120+
const cmd = `${binary} ${args.join(" ")}`;
121+
if (GITHUB_ACTIONS_OUTPUT)
122+
core.startGroup(binary);
123+
logCommand(cmd);
124+
try {
125+
return await spawnCaptureStdout(binary, args);
126+
} catch(e) {
127+
logError(e.stdoutString);
128+
throw e;
129+
} finally {
130+
if (GITHUB_ACTIONS_OUTPUT)
131+
core.endGroup();
132+
}
133+
}
134+
135+
const SPAWN_OPTIONS = Object.freeze({
136+
stdio: ["inherit", "pipe", "inherit"]
137+
});
138+
139+
async function spawnCaptureStdout(binary, args, options={}) {
140+
options = Object.assign(options, SPAWN_OPTIONS);
141+
const childProcess = spawn(binary, args, options);
142+
childProcess.stdout.pipe(process.stdout);
143+
return new Promise((resolve, reject) => {
144+
childProcess.stdoutString = "";
145+
childProcess.stdio[1].on("data", (data) => {
146+
childProcess.stdoutString += data.toString();
147+
});
148+
childProcess.on("close", (code) => {
149+
if (code === 0) {
150+
resolve(childProcess);
151+
} else {
152+
// Reject the Promise with an Error on failure
153+
const error = new Error(`Command failed with exit code ${code}: ${binary} ${args.join(" ")}`);
154+
error.process = childProcess;
155+
error.stdout = childProcess.stdoutString;
156+
error.exitCode = code;
157+
reject(error);
158+
}
159+
});
160+
childProcess.on("error", reject);
161+
})
162+
}

0 commit comments

Comments
 (0)