@@ -160,6 +160,13 @@ def run_elf2image(
160160 print (e .output )
161161 raise
162162
163+ @staticmethod
164+ def assertAllFF (some_bytes ):
165+ """Assert that the given bytes are all 0xFF (erased flash state)"""
166+ assert b"\xff " * len (some_bytes ) == some_bytes , (
167+ "Expected all 0xFF bytes, but found different values"
168+ )
169+
163170
164171class TestESP8266V1Image (BaseTestCase ):
165172 ELF = "esp8266-nonosssdk20-iotdemo.elf"
@@ -344,6 +351,84 @@ def test_ram_only_header(self):
344351 image = self ._test_elf2image (ELF , BIN , ["--ram-only-header" ])
345352 assert len (image .segments ) == 2
346353
354+ @pytest .fixture (scope = "class" )
355+ def reference_bin (self ):
356+ BASE_NAME = "esp32-bootloader"
357+ BIN = f"{ BASE_NAME } -reference.bin"
358+ self .run_elf2image ("esp32" , f"{ BASE_NAME } .elf" )
359+ os .rename (f"{ BASE_NAME } .bin" , BIN )
360+ yield BIN
361+ # Cleanup the reference binary after the test
362+ try_delete (BIN )
363+
364+ def test_pad_to_size (self , reference_bin : str ):
365+ """Test that --pad-to-size correctly pads output binary to specified size"""
366+ ELF = "esp32-bootloader.elf"
367+ BIN = "esp32-bootloader.bin"
368+
369+ try :
370+ # Generate the padded binary with 1MB size
371+ self .run_elf2image ("esp32" , ELF , extra_args = ["--pad-to-size" , "1MB" ])
372+
373+ # Get the size of the reference binary
374+ normal_size = os .path .getsize (reference_bin )
375+
376+ # Check that the padded binary is exactly 1MB
377+ padded_size = os .path .getsize (BIN )
378+ expected_size = 0x100000 # 1MB in bytes
379+ assert padded_size == expected_size , (
380+ f"Expected { expected_size } bytes (1MB), got { padded_size } bytes"
381+ )
382+
383+ # Check that the original content is preserved at the beginning
384+ with open (reference_bin , "rb" ) as f :
385+ original_content = f .read ()
386+ with open (BIN , "rb" ) as f :
387+ padded_content = f .read ()
388+
389+ assert padded_content [:normal_size ] == original_content , (
390+ "Original content should be preserved at the beginning of padded file"
391+ )
392+
393+ # Check that the padding is filled with 0xFF bytes (erased flash state)
394+ padding = padded_content [normal_size :]
395+ expected_padding_size = expected_size - normal_size
396+ assert len (padding ) == expected_padding_size , (
397+ f"Padding should be { expected_padding_size } bytes, got { len (padding )} "
398+ )
399+ self .assertAllFF (padding )
400+
401+ finally :
402+ try_delete (BIN )
403+
404+ @pytest .mark .parametrize ("size" , ["512KB" , "2MB" , "4MB" ])
405+ def test_pad_to_size_different_sizes (self , size : str , reference_bin : str ):
406+ """Test --pad-to-size with different size values"""
407+ ELF = "esp32-bootloader.elf"
408+ BIN = "esp32-bootloader.bin"
409+
410+ expected_bytes = esptool .util .flash_size_bytes (size )
411+ try :
412+ # Generate the padded binary
413+ self .run_elf2image ("esp32" , ELF , extra_args = ["--pad-to-size" , size ])
414+
415+ # Check the file size
416+ padded_size = os .path .getsize (BIN )
417+ assert padded_size == expected_bytes , (
418+ f"Expected { expected_bytes } bytes for { size } , got { padded_size } "
419+ )
420+
421+ # Check that padding is 0xFF
422+ with open (BIN , "rb" ) as f :
423+ padded_content = f .read ()
424+
425+ # Get original size from the normal binary and check that padding
426+ normal_size = os .path .getsize (reference_bin )
427+ self .assertAllFF (padded_content [normal_size :])
428+
429+ finally :
430+ try_delete (BIN )
431+
347432
348433class TestESP8266FlashHeader (BaseTestCase ):
349434 def test_2mb (self ):
0 commit comments