Skip to content

Commit 88bfef1

Browse files
committed
Move helper into test_other.py
We no longer have size test in test_browser, so we can colocate helper closer to its usages.
1 parent 08d1f72 commit 88bfef1

File tree

2 files changed

+76
-79
lines changed

2 files changed

+76
-79
lines changed

test/common.py

Lines changed: 1 addition & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@
55

66
from enum import Enum
77
from functools import wraps
8-
import gzip
9-
import json
10-
from math import inf
118
from pathlib import Path
129
from subprocess import PIPE, STDOUT
13-
from typing import Dict, List, Tuple
10+
from typing import Dict, Tuple
1411
from urllib.parse import unquote, unquote_plus, urlparse, parse_qs
1512
from http.server import HTTPServer, SimpleHTTPRequestHandler
1613
import contextlib
@@ -1697,77 +1694,6 @@ def assertBinaryEqual(self, file1, file2):
16971694
self.assertEqual(read_binary(file1),
16981695
read_binary(file2))
16991696

1700-
def check_output_sizes(self, outputs: List[str], metadata=None):
1701-
test_name = self.id().split('.')[-1]
1702-
results_file = test_file('code_size', test_name + '.json')
1703-
1704-
expected_results: dict = {}
1705-
try:
1706-
expected_results = json.loads(read_file(results_file))
1707-
except Exception:
1708-
if not EMTEST_REBASELINE:
1709-
raise
1710-
1711-
obtained_results = {}
1712-
1713-
total_output_size = 0
1714-
total_expected_size = 0
1715-
total_output_size_gz = 0
1716-
total_expected_size_gz = 0
1717-
for f in outputs:
1718-
f_gz = f + '.gz'
1719-
expected_size = expected_results.get(f, inf)
1720-
expected_size_gz = expected_results.get(f_gz, inf)
1721-
contents = read_binary(f)
1722-
size = len(contents)
1723-
size_gz = len(gzip.compress(contents))
1724-
1725-
obtained_results[f] = size
1726-
obtained_results[f_gz] = size_gz
1727-
1728-
if not EMTEST_REBASELINE and size != expected_size and (f.endswith(('.js', '.html'))):
1729-
print('Contents of ' + f + ': ')
1730-
print(contents.decode('utf-8', errors='replace'))
1731-
1732-
def print_diff(title, actual, expected):
1733-
diff = actual - expected
1734-
s = f'{title}={actual}, expected {expected}'
1735-
if diff > 0:
1736-
s += f', delta={diff} ({diff * 100.0 / expected:+.2f}%)'
1737-
print(s)
1738-
1739-
print_diff(f'size of {f}', size, expected_size)
1740-
print_diff(f'size of {f_gz}', size_gz, expected_size_gz)
1741-
1742-
# N.B. even though the test code above prints out gzip compressed sizes, regression testing is done against uncompressed sizes
1743-
# this is because optimizing for compressed sizes can be unpredictable and sometimes counterproductive
1744-
total_output_size += size
1745-
total_expected_size += expected_size
1746-
1747-
total_output_size_gz += size_gz
1748-
total_expected_size_gz += expected_size_gz
1749-
1750-
if len(outputs) > 1:
1751-
obtained_results['total'] = total_output_size
1752-
obtained_results['total_gz'] = total_output_size_gz
1753-
1754-
print_diff('Total output size', total_output_size, total_expected_size)
1755-
print_diff('Total output size gzipped', total_output_size_gz, total_expected_size_gz)
1756-
1757-
if metadata is not None:
1758-
obtained_results.update(metadata)
1759-
1760-
if EMTEST_REBASELINE:
1761-
create_file(results_file, json.dumps(obtained_results, indent=2) + '\n', absolute=True)
1762-
else:
1763-
if total_output_size > total_expected_size:
1764-
print(f'Oops, overall generated code size regressed by {total_output_size - total_expected_size} bytes!')
1765-
print('If this is expected, rerun the test with --rebaseline to update the expected sizes')
1766-
if total_output_size < total_expected_size:
1767-
print(f'Hey amazing, overall generated code size was improved by {total_expected_size - total_output_size} bytes!')
1768-
print('If this is expected, rerun the test with --rebaseline to update the expected sizes')
1769-
self.assertDictEqual(obtained_results, expected_results)
1770-
17711697
library_cache: Dict[str, Tuple[str, object]] = {}
17721698

17731699
def get_build_dir(self):

test/test_other.py

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import importlib
1313
import itertools
1414
import json
15+
from math import inf
1516
import os
1617
import re
1718
import select
@@ -9245,6 +9246,76 @@ def build(args):
92459246
# adding --metrics should not affect code size
92469247
self.assertEqual(base_size, os.path.getsize('a.out.wasm'))
92479248

9249+
def check_output_sizes(self, *outputs: str, **metadata):
9250+
test_name = self.id().split('.')[-1]
9251+
results_file = test_file('code_size', test_name + '.json')
9252+
9253+
expected_results: dict = {}
9254+
try:
9255+
expected_results = json.loads(read_file(results_file))
9256+
except Exception:
9257+
if not common.EMTEST_REBASELINE:
9258+
raise
9259+
9260+
obtained_results = {}
9261+
9262+
total_output_size = 0
9263+
total_expected_size = 0
9264+
total_output_size_gz = 0
9265+
total_expected_size_gz = 0
9266+
for f in outputs:
9267+
f_gz = f + '.gz'
9268+
expected_size = expected_results.get(f, inf)
9269+
expected_size_gz = expected_results.get(f_gz, inf)
9270+
contents = read_binary(f)
9271+
size = len(contents)
9272+
size_gz = len(gzip.compress(contents))
9273+
9274+
obtained_results[f] = size
9275+
obtained_results[f_gz] = size_gz
9276+
9277+
if not common.EMTEST_REBASELINE and size != expected_size and (f.endswith(('.js', '.html'))):
9278+
print('Contents of ' + f + ': ')
9279+
print(contents.decode('utf-8', errors='replace'))
9280+
9281+
def print_diff(title, actual, expected):
9282+
diff = actual - expected
9283+
s = f'{title}={actual}, expected {expected}'
9284+
if diff > 0:
9285+
s += f', delta={diff} ({diff * 100.0 / expected:+.2f}%)'
9286+
print(s)
9287+
9288+
print_diff(f'size of {f}', size, expected_size)
9289+
print_diff(f'size of {f_gz}', size_gz, expected_size_gz)
9290+
9291+
# N.B. even though the test code above prints out gzip compressed sizes, regression testing is done against uncompressed sizes
9292+
# this is because optimizing for compressed sizes can be unpredictable and sometimes counterproductive
9293+
total_output_size += size
9294+
total_expected_size += expected_size
9295+
9296+
total_output_size_gz += size_gz
9297+
total_expected_size_gz += expected_size_gz
9298+
9299+
if len(outputs) > 1:
9300+
obtained_results['total'] = total_output_size
9301+
obtained_results['total_gz'] = total_output_size_gz
9302+
9303+
print_diff('Total output size', total_output_size, total_expected_size)
9304+
print_diff('Total output size gzipped', total_output_size_gz, total_expected_size_gz)
9305+
9306+
obtained_results.update(metadata)
9307+
9308+
if common.EMTEST_REBASELINE:
9309+
create_file(results_file, json.dumps(obtained_results, indent=2) + '\n', absolute=True)
9310+
else:
9311+
if total_output_size > total_expected_size:
9312+
print(f'Oops, overall generated code size regressed by {total_output_size - total_expected_size} bytes!')
9313+
print('If this is expected, rerun the test with --rebaseline to update the expected sizes')
9314+
if total_output_size < total_expected_size:
9315+
print(f'Hey amazing, overall generated code size was improved by {total_expected_size - total_output_size} bytes!')
9316+
print('If this is expected, rerun the test with --rebaseline to update the expected sizes')
9317+
self.assertDictEqual(obtained_results, expected_results)
9318+
92489319
@crossplatform
92499320
def test_unoptimized_code_size(self):
92509321
# We don't care too about unoptimized code size but we would like to keep it
@@ -9255,7 +9326,7 @@ def test_unoptimized_code_size(self):
92559326
self.build('hello_world.c', cflags=['-O0', '--output-eol=linux', '-sASSERTIONS=0'], output_basename='no_asserts')
92569327
self.build('hello_world.c', cflags=['-O0', '--output-eol=linux', '-sSTRICT'], output_basename='strict')
92579328

9258-
self.check_output_sizes(['hello_world.js', 'hello_world.wasm', 'no_asserts.js', 'no_asserts.wasm', 'strict.js', 'strict.wasm'])
9329+
self.check_output_sizes('hello_world.js', 'hello_world.wasm', 'no_asserts.js', 'no_asserts.wasm', 'strict.js', 'strict.wasm')
92599330

92609331
def run_codesize_test(self, filename, cflags, check_funcs=True, check_full_js=False):
92619332
# in -Os, -Oz, we remove imports wasm doesn't need
@@ -9328,7 +9399,7 @@ def strip_numeric_suffixes(funcname):
93289399
funcs.sort()
93299400
info['funcs'] = [strip_numeric_suffixes(f) for f in funcs]
93309401

9331-
self.check_output_sizes(outputs, info)
9402+
self.check_output_sizes(*outputs, **info)
93329403

93339404
@parameterized({
93349405
'O0': ([], True),
@@ -11889,7 +11960,7 @@ def test_minimal_runtime_code_size(self, test_name, wasm2js, compare_js_output=F
1188911960
self.run_process(terser + ['-b', 'beautify=true', 'a.js', '-o', 'pretty.js'], env=shared.env_with_node_in_path())
1189011961
self.assertFileContents(js_out, read_file('pretty.js'))
1189111962

11892-
self.check_output_sizes(outputs)
11963+
self.check_output_sizes(*outputs)
1189311964

1189411965
# Tests the library_c_preprocessor.js functionality.
1189511966
@crossplatform
@@ -12333,7 +12404,7 @@ def test(args):
1233312404
# Changing this option to [] should decrease code size.
1233412405
self.assertLess(changed, normal)
1233512406
# Check an absolute code size as well.
12336-
self.check_output_sizes(['a.out.js'])
12407+
self.check_output_sizes('a.out.js')
1233712408

1233812409
def test_INCOMING_MODULE_JS_API_missing(self):
1233912410
create_file('pre.js', 'Module.onRuntimeInitialized = () => out("initialized");')

0 commit comments

Comments
 (0)