@@ -8186,7 +8186,17 @@ def test(args, closure, opt):
8186
8186
# The no_windows/no_mac decorators also solve that problem.
8187
8187
@no_windows ("Code size is slightly different on Windows" )
8188
8188
@no_mac ("Code size is slightly different on Mac" )
8189
- def test_minimal_runtime_code_size (self ):
8189
+ @parameterized ({
8190
+ 'hello_world_wasm' : ('hello_world' , False ),
8191
+ 'hello_world_wasm2js' : ('hello_world' , True ),
8192
+ 'random_printf_wasm' : ('random_printf' , False ),
8193
+ 'random_printf_wasm2js' : ('random_printf' , True ),
8194
+ 'hello_webgl_wasm' : ('hello_webgl' , False ),
8195
+ 'hello_webgl_wasm2js' : ('hello_webgl' , True ),
8196
+ 'hello_webgl2_wasm' : ('hello_webgl2' , False ),
8197
+ 'hello_webgl2_wasm2js' : ('hello_webgl2' , True ),
8198
+ })
8199
+ def test_minimal_runtime_code_size (self , test_name , js ):
8190
8200
smallest_code_size_args = ['-s' , 'MINIMAL_RUNTIME=2' ,
8191
8201
'-s' , 'ENVIRONMENT=web' ,
8192
8202
'-s' , 'TEXTDECODER=2' ,
@@ -8227,125 +8237,118 @@ def test_minimal_runtime_code_size(self):
8227
8237
'-s' , 'MODULARIZE=1' ]
8228
8238
hello_webgl2_sources = hello_webgl_sources + ['-s' , 'MAX_WEBGL_VERSION=2' ]
8229
8239
8240
+ sources = {
8241
+ 'hello_world' : hello_world_sources ,
8242
+ 'random_printf' : random_printf_sources ,
8243
+ 'hello_webgl' : hello_webgl_sources ,
8244
+ 'hello_webgl2' : hello_webgl2_sources }[test_name ]
8245
+
8230
8246
def print_percent (actual , expected ):
8231
8247
if actual == expected :
8232
8248
return ''
8233
8249
return ' ({:+.2f}%)' .format ((actual - expected ) * 100.0 / expected )
8234
8250
8235
- for js in [False , True ]:
8236
- for sources , name in [
8237
- [hello_world_sources , 'hello_world' ],
8238
- [random_printf_sources , 'random_printf' ],
8239
- [hello_webgl_sources , 'hello_webgl' ],
8240
- [hello_webgl2_sources , 'hello_webgl2' ]
8241
- ]:
8251
+ outputs = ['a.html' , 'a.js' ]
8242
8252
8243
- outputs = [ 'a.html' , 'a.js' ]
8253
+ args = smallest_code_size_args [: ]
8244
8254
8245
- test_name = name
8255
+ if js :
8256
+ outputs += ['a.mem' ]
8257
+ args += wasm2js
8258
+ test_name += '_wasm2js'
8259
+ else :
8260
+ outputs += ['a.wasm' ]
8261
+ test_name += '_wasm'
8246
8262
8247
- args = smallest_code_size_args [:]
8263
+ if 'SINGLE_FILE=1' in sources :
8264
+ outputs = ['a.html' ]
8248
8265
8266
+ results_file = path_from_root ('tests' , 'code_size' , test_name + '.json' )
8267
+
8268
+ expected_results = {}
8269
+ try :
8270
+ expected_results = json .loads (open (results_file , 'r' ).read ())
8271
+ except Exception :
8272
+ if not os .environ .get ('EMTEST_REBASELINE' ):
8273
+ raise
8274
+
8275
+ args = [EMCC , '-o' , 'a.html' ] + args + sources
8276
+ print (shared .shlex_join (args ))
8277
+ self .run_process (args )
8278
+
8279
+ def get_file_gzipped_size (f ):
8280
+ f_gz = f + '.gz'
8281
+ with gzip .open (f_gz , 'wb' ) as gzf :
8282
+ gzf .write (open (f , 'rb' ).read ())
8283
+ size = os .path .getsize (f_gz )
8284
+ try_delete (f_gz )
8285
+ return size
8286
+
8287
+ obtained_results = {}
8288
+ total_output_size = 0
8289
+ total_expected_size = 0
8290
+ total_output_size_gz = 0
8291
+ total_expected_size_gz = 0
8292
+ for f in outputs :
8293
+ f_gz = f + '.gz'
8294
+ expected_size = expected_results [f ] if f in expected_results else float ('inf' )
8295
+ expected_size_gz = expected_results [f_gz ] if f_gz in expected_results else float ('inf' )
8296
+ size = os .path .getsize (f )
8297
+ size_gz = get_file_gzipped_size (f )
8298
+
8299
+ obtained_results [f ] = size
8300
+ obtained_results [f_gz ] = size_gz
8301
+
8302
+ if size != expected_size and (f .endswith ('.js' ) or f .endswith ('.html' )):
8303
+ print ('Contents of ' + f + ': ' )
8304
+ print (open (f , 'r' ).read ())
8305
+
8306
+ print ('size of ' + f + ' == ' + str (size ) + ', expected ' + str (expected_size ) + ', delta=' + str (size - expected_size ) + print_percent (size , expected_size ))
8307
+ print ('size of ' + f_gz + ' == ' + str (size_gz ) + ', expected ' + str (expected_size_gz ) + ', delta=' + str (size_gz - expected_size_gz ) + print_percent (size_gz , expected_size_gz ))
8308
+
8309
+ # Hack: Generated .mem initializer files have different sizes on different
8310
+ # platforms (Windows gives x, CircleCI Linux gives x-17 bytes, my home
8311
+ # Linux gives x+2 bytes..). Likewise asm.js files seem to be affected by
8312
+ # the LLVM IR text names, which lead to asm.js names, which leads to
8313
+ # difference code size, which leads to different relooper choices,
8314
+ # as a result leading to slightly different total code sizes.
8315
+ # Also as of July 16, 2020, wasm2js files have different sizes on
8316
+ # different platforms (Windows and MacOS improved to give a slightly
8317
+ # better thing than Linux does, which didn't change; this just
8318
+ # started to happen on CI, not in response to a code update, so it
8319
+ # may have been present all along but just noticed now; it only
8320
+ # happens in wasm2js, so it may be platform-nondeterminism in closure
8321
+ # compiler).
8322
+ # TODO: identify what is causing this. meanwhile allow some amount of slop
8323
+ if not os .environ .get ('EMTEST_REBASELINE' ):
8249
8324
if js :
8250
- outputs += ['a.mem' ]
8251
- args += wasm2js
8252
- test_name += '_wasm2js'
8325
+ slop = 30
8253
8326
else :
8254
- outputs += ['a.wasm' ]
8255
- test_name += '_wasm'
8256
-
8257
- if 'SINGLE_FILE=1' in sources :
8258
- outputs = ['a.html' ]
8327
+ slop = 20
8328
+ if size <= expected_size + slop and size >= expected_size - slop :
8329
+ size = expected_size
8259
8330
8260
- results_file = path_from_root ('tests' , 'code_size' , test_name + '.json' )
8331
+ # N.B. even though the test code above prints out gzip compressed sizes, regression testing is done against uncompressed sizes
8332
+ # this is because optimizing for compressed sizes can be unpredictable and sometimes counterproductive
8333
+ total_output_size += size
8334
+ total_expected_size += expected_size
8261
8335
8262
- print ('\n -----------------------------\n ' + test_name )
8336
+ total_output_size_gz += size_gz
8337
+ total_expected_size_gz += expected_size_gz
8263
8338
8264
- expected_results = {}
8265
- try :
8266
- expected_results = json .loads (open (results_file , 'r' ).read ())
8267
- except Exception :
8268
- if not os .environ .get ('EMTEST_REBASELINE' ):
8269
- raise
8339
+ obtained_results ['total' ] = total_output_size
8340
+ obtained_results ['total_gz' ] = total_output_size_gz
8341
+ print ('Total output size=' + str (total_output_size ) + ' bytes, expected total size=' + str (total_expected_size ) + ', delta=' + str (total_output_size - total_expected_size ) + print_percent (total_output_size , total_expected_size ))
8342
+ print ('Total output size gzipped=' + str (total_output_size_gz ) + ' bytes, expected total size gzipped=' + str (total_expected_size_gz ) + ', delta=' + str (total_output_size_gz - total_expected_size_gz ) + print_percent (total_output_size_gz , total_expected_size_gz ))
8270
8343
8271
- args = [EMCC , '-o' , 'a.html' ] + args + sources
8272
- print ('\n ' + ' ' .join (args ))
8273
- self .run_process (args )
8274
- print ('\n ' )
8275
-
8276
- def get_file_gzipped_size (f ):
8277
- f_gz = f + '.gz'
8278
- with gzip .open (f_gz , 'wb' ) as gzf :
8279
- gzf .write (open (f , 'rb' ).read ())
8280
- size = os .path .getsize (f_gz )
8281
- try_delete (f_gz )
8282
- return size
8283
-
8284
- obtained_results = {}
8285
- total_output_size = 0
8286
- total_expected_size = 0
8287
- total_output_size_gz = 0
8288
- total_expected_size_gz = 0
8289
- for f in outputs :
8290
- f_gz = f + '.gz'
8291
- expected_size = expected_results [f ] if f in expected_results else float ('inf' )
8292
- expected_size_gz = expected_results [f_gz ] if f_gz in expected_results else float ('inf' )
8293
- size = os .path .getsize (f )
8294
- size_gz = get_file_gzipped_size (f )
8295
-
8296
- obtained_results [f ] = size
8297
- obtained_results [f_gz ] = size_gz
8298
-
8299
- if size != expected_size and (f .endswith ('.js' ) or f .endswith ('.html' )):
8300
- print ('Contents of ' + f + ': ' )
8301
- print (open (f , 'r' ).read ())
8302
-
8303
- print ('size of ' + f + ' == ' + str (size ) + ', expected ' + str (expected_size ) + ', delta=' + str (size - expected_size ) + print_percent (size , expected_size ))
8304
- print ('size of ' + f_gz + ' == ' + str (size_gz ) + ', expected ' + str (expected_size_gz ) + ', delta=' + str (size_gz - expected_size_gz ) + print_percent (size_gz , expected_size_gz ))
8305
-
8306
- # Hack: Generated .mem initializer files have different sizes on different
8307
- # platforms (Windows gives x, CircleCI Linux gives x-17 bytes, my home
8308
- # Linux gives x+2 bytes..). Likewise asm.js files seem to be affected by
8309
- # the LLVM IR text names, which lead to asm.js names, which leads to
8310
- # difference code size, which leads to different relooper choices,
8311
- # as a result leading to slightly different total code sizes.
8312
- # Also as of July 16, 2020, wasm2js files have different sizes on
8313
- # different platforms (Windows and MacOS improved to give a slightly
8314
- # better thing than Linux does, which didn't change; this just
8315
- # started to happen on CI, not in response to a code update, so it
8316
- # may have been present all along but just noticed now; it only
8317
- # happens in wasm2js, so it may be platform-nondeterminism in closure
8318
- # compiler).
8319
- # TODO: identify what is causing this. meanwhile allow some amount of slop
8320
- if not os .environ .get ('EMTEST_REBASELINE' ):
8321
- if js :
8322
- slop = 30
8323
- else :
8324
- slop = 20
8325
- if size <= expected_size + slop and size >= expected_size - slop :
8326
- size = expected_size
8327
-
8328
- # N.B. even though the test code above prints out gzip compressed sizes, regression testing is done against uncompressed sizes
8329
- # this is because optimizing for compressed sizes can be unpredictable and sometimes counterproductive
8330
- total_output_size += size
8331
- total_expected_size += expected_size
8332
-
8333
- total_output_size_gz += size_gz
8334
- total_expected_size_gz += expected_size_gz
8335
-
8336
- obtained_results ['total' ] = total_output_size
8337
- obtained_results ['total_gz' ] = total_output_size_gz
8338
- print ('Total output size=' + str (total_output_size ) + ' bytes, expected total size=' + str (total_expected_size ) + ', delta=' + str (total_output_size - total_expected_size ) + print_percent (total_output_size , total_expected_size ))
8339
- print ('Total output size gzipped=' + str (total_output_size_gz ) + ' bytes, expected total size gzipped=' + str (total_expected_size_gz ) + ', delta=' + str (total_output_size_gz - total_expected_size_gz ) + print_percent (total_output_size_gz , total_expected_size_gz ))
8340
-
8341
- if os .environ .get ('EMTEST_REBASELINE' ):
8342
- open (results_file , 'w' ).write (json .dumps (obtained_results , indent = 2 ) + '\n ' )
8343
- else :
8344
- if total_output_size > total_expected_size :
8345
- print ('Oops, overall generated code size regressed by ' + str (total_output_size - total_expected_size ) + ' bytes!' )
8346
- if total_output_size < total_expected_size :
8347
- print ('Hey amazing, overall generated code size was improved by ' + str (total_expected_size - total_output_size ) + ' bytes! Rerun test with other.test_minimal_runtime_code_size with EMTEST_REBASELINE=1 to update the expected sizes!' )
8348
- self .assertEqual (total_output_size , total_expected_size )
8344
+ if os .environ .get ('EMTEST_REBASELINE' ):
8345
+ open (results_file , 'w' ).write (json .dumps (obtained_results , indent = 2 ) + '\n ' )
8346
+ else :
8347
+ if total_output_size > total_expected_size :
8348
+ print ('Oops, overall generated code size regressed by ' + str (total_output_size - total_expected_size ) + ' bytes!' )
8349
+ if total_output_size < total_expected_size :
8350
+ print ('Hey amazing, overall generated code size was improved by ' + str (total_expected_size - total_output_size ) + ' bytes! Rerun test with other.test_minimal_runtime_code_size with EMTEST_REBASELINE=1 to update the expected sizes!' )
8351
+ self .assertEqual (total_output_size , total_expected_size )
8349
8352
8350
8353
# Test that legacy settings that have been fixed to a specific value and their value can no longer be changed,
8351
8354
def test_legacy_settings_forbidden_to_change (self ):
0 commit comments