Skip to content

Commit 1041427

Browse files
authored
fix: flaky tests (#19)
1 parent d18d4e2 commit 1041427

File tree

7 files changed

+63
-31
lines changed

7 files changed

+63
-31
lines changed

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
indent_style = space
8+
indent_size = 4
9+
trim_trailing_whitespace = true

.gitattributes

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
* text=auto eol=lf
2+
3+
# Keep common scripts LF on all platforms
4+
*.sh text eol=lf
5+
*.ts text eol=lf
6+
*.tsx text eol=lf
7+
*.js text eol=lf
8+
*.json text eol=lf
9+
*.md text eol=lf
10+
*.yml text eol=lf
11+
*.yaml text eol=lf
12+
*.py text eol=lf

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
"benchmark:add": "jest --runTestsByPath tests/Benchmark.spec.ts --verbose --testPathIgnorePatterns=/node_modules/ --testPathIgnorePatterns=/dist/ -- --add",
1111
"benchmark:replace": "jest --runTestsByPath tests/Benchmark.spec.ts --verbose --testPathIgnorePatterns=/node_modules/ --testPathIgnorePatterns=/dist/ -- --replace",
1212
"benchmark:print": "node tests/print-benchmark.js",
13-
"format": "npx prettier --write \"**/*.{js,ts,tsx,json,md,yml,yaml}\" && UV_CACHE_DIR=.uv-cache uv run ruff format .",
14-
"format:check": "npx prettier --check \"**/*.{js,ts,tsx,json,md,yml,yaml}\" && UV_CACHE_DIR=.uv-cache uv run ruff format --check .",
15-
"lint": "UV_CACHE_DIR=.uv-cache uv run ruff check . && npx eslint .",
13+
"format": "npx prettier --write \"**/*.{js,ts,tsx,json,md,yml,yaml}\" && uv run ruff format .",
14+
"format:check": "npx prettier --check \"**/*.{js,ts,tsx,json,md,yml,yaml}\" && uv run ruff format --check .",
15+
"lint": "uv run ruff check . && npx eslint .",
1616
"check:kernel": "UV_CACHE_DIR=.uv-cache uv run python scripts/check_kernel.py",
1717
"ci": "npm run format:check && npm run lint && npm run check:kernel && npm test"
1818
},

src/generator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,7 @@ def process_hit(
943943

944944
init_obj = {
945945
"code": base64.urlsafe_b64encode(boc_code).decode("utf-8"),
946-
"fixedPrefixLength": 0 if fpl_val is None else fpl_val,
946+
"fixedPrefixLength": None if fpl_val is None else fpl_val,
947947
"special": None
948948
if special is None
949949
else {"tick": bool(special[0]), "tock": bool(special[1])},

tests/Benchmark.spec.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,7 @@ const benchDeviceIds = parseDeviceIds(benchDevices);
6969
type PythonCmd = { exe: string; args: string[] };
7070

7171
const resolvePython = (): PythonCmd => {
72-
const candidates =
73-
process.platform === 'win32'
74-
? ['py', 'py -3', 'python3', 'python']
75-
: ['python3', 'python'];
72+
const candidates = process.platform === 'win32' ? ['py', 'py -3', 'python3', 'python'] : ['python3', 'python'];
7673
for (const cmd of candidates) {
7774
const [exe, ...args] = cmd.split(' ');
7875
try {
@@ -137,9 +134,7 @@ const normalizeDeviceName = (name: string) =>
137134

138135
const detectedDevicesAll = detectDevices().map(normalizeDeviceName).filter(Boolean);
139136
const selectedDevices = benchDeviceIds
140-
? benchDeviceIds
141-
.map((i) => detectedDevicesAll[i])
142-
.filter((n): n is string => typeof n === 'string' && n.length > 0)
137+
? benchDeviceIds.map((i) => detectedDevicesAll[i]).filter((n): n is string => typeof n === 'string' && n.length > 0)
143138
: detectedDevicesAll;
144139

145140
const benchCases: BenchCase[] = (() => {
@@ -319,10 +314,10 @@ const gpuOk = gpuAvailable();
319314
const entry = entries[i];
320315
const prev = i > 0 ? entries[i - 1] : null;
321316

322-
const dt = new Date(entry.timestamp * 1000);
323-
const iso = dt.toISOString().slice(0, 10);
324-
const [y, m, d] = iso.split('-');
325-
const dateStr = `${d}.${m}.${y.slice(2)}`; // DD.MM.YY
317+
const dt = new Date(entry.timestamp * 1000);
318+
const iso = dt.toISOString().slice(0, 10);
319+
const [y, m, d] = iso.split('-');
320+
const dateStr = `${d}.${m}.${y.slice(2)}`; // DD.MM.YY
326321

327322
const row: Record<string, unknown> = {
328323
run: raw(String(entry.title)),
@@ -406,8 +401,7 @@ const gpuOk = gpuAvailable();
406401
: detectedDevicesAll.length
407402
? detectedDevicesAll
408403
: [DEFAULT_DEVICE];
409-
const resolvedDeviceName =
410-
effectiveDevices.length === 1 ? effectiveDevices[0] : effectiveDevices.join(' + ');
404+
const resolvedDeviceName = effectiveDevices.length === 1 ? effectiveDevices[0] : effectiveDevices.join(' + ');
411405

412406
const resultsMap = readResultsMap();
413407
const priorEntries: BenchEntry[] = resultsMap[resolvedDeviceName] ?? [];

tests/Generator.spec.ts

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@ const MASTERCHAIN_VARIANTS = [false, true];
2323
type PythonCmd = { exe: string; args: string[] };
2424

2525
const resolvePython = (): PythonCmd => {
26-
const candidates =
27-
process.platform === 'win32'
28-
? ['py', 'py -3', 'python3', 'python']
29-
: ['python3', 'python'];
26+
const candidates = process.platform === 'win32' ? ['py', 'py -3', 'python3', 'python'] : ['python3', 'python'];
3027
for (const cmd of candidates) {
3128
const [exe, ...args] = cmd.split(' ');
3229
try {
@@ -43,7 +40,9 @@ const resolvePython = (): PythonCmd => {
4340

4441
const PYTHON = resolvePython();
4542

46-
function gpuAvailable(): boolean {
43+
type GpuProbe = { ok: boolean; reason?: string };
44+
45+
function gpuAvailable(): GpuProbe {
4746
const probe = `
4847
try:
4948
import pyopencl as cl
@@ -54,11 +53,26 @@ try:
5453
except Exception:
5554
pass
5655
print("1" if devs else "0")
57-
except Exception:
58-
print("0")
56+
except Exception as e:
57+
print("err:" + repr(e))
5958
`;
60-
const res = spawnSync(PYTHON.exe, [...PYTHON.args, '-c', probe], { cwd: 'src', encoding: 'utf8' });
61-
return res.status === 0 && res.stdout.trim() === '1';
59+
const res = spawnSync(PYTHON.exe, [...PYTHON.args, '-c', probe], {
60+
cwd: 'src',
61+
encoding: 'utf8',
62+
});
63+
64+
if (res.error) {
65+
return { ok: false, reason: `spawn failed: ${res.error.message}` };
66+
}
67+
const out = (res.stdout || '').trim();
68+
if (res.status !== 0) {
69+
const err = (res.stderr || out || `exit ${res.status}`).trim();
70+
return { ok: false, reason: `python exited ${res.status}: ${err}` };
71+
}
72+
if (out === '1') {
73+
return { ok: true };
74+
}
75+
return { ok: false, reason: `pyopencl unavailable or no OpenCL devices (stdout="${out}")` };
6276
}
6377

6478
type PyInfo = { start_digit_base: number };
@@ -218,9 +232,13 @@ for (let len = 1; len <= 4; len++) {
218232

219233
const scenarios: Scenario[] = [...startScenarios, ...endScenarios, ...comboScenarios];
220234

221-
const gpuOk = gpuAvailable();
235+
const gpu = gpuAvailable();
236+
if (!gpu.ok) {
237+
// Log once so it shows up even when the suite is skipped.
238+
console.warn(`[generator.py GPU matrix] skipping: ${gpu.reason}`);
239+
}
222240

223-
(gpuOk ? describe : describe.skip)('generator.py GPU matrix', () => {
241+
(gpu.ok ? describe : describe.skip)('generator.py GPU matrix', () => {
224242
const owner = Address.parseFriendly(OWNER).address;
225243

226244
it.each(scenarios)('$name', (scenario) => {
@@ -260,7 +278,7 @@ const gpuOk = gpuAvailable();
260278
// Rebuild StateInit and recompute contract address, compare to reported.
261279
type HitInit = {
262280
code: string;
263-
fixedPrefixLength?: number;
281+
fixedPrefixLength?: number | null;
264282
special?: { tick: boolean; tock: boolean } | null;
265283
};
266284
type HitConfig = {
@@ -276,7 +294,7 @@ const gpuOk = gpuAvailable();
276294
const stateInit: StateInit & { special?: { tick: boolean; tock: boolean } } = {
277295
code: codeCell,
278296
};
279-
if (init.fixedPrefixLength && init.fixedPrefixLength > 0) {
297+
if (init.fixedPrefixLength !== undefined && init.fixedPrefixLength !== null) {
280298
stateInit.splitDepth = init.fixedPrefixLength;
281299
}
282300
if (init.special) {

tests/print-benchmark.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ const normalizeRate = (rate, length, ci) => {
3131
};
3232
const raw = (s) => ({ [Symbol.for('nodejs.util.inspect.custom')]: () => s });
3333

34-
3534
const argv = process.argv;
3635
let deviceFilter = null;
3736
for (let i = 0; i < argv.length; i++) {

0 commit comments

Comments
 (0)