Skip to content

Commit 48c6129

Browse files
committed
fixed integration test on clasic esp32
1 parent 811ae12 commit 48c6129

3 files changed

Lines changed: 54 additions & 29 deletions

File tree

mpytool/mpy.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -534,21 +534,23 @@ def detect_chunk_size(self):
534534
free = self._mpy_comm.exec_eval("gc.mem_free()")
535535
except _mpy_comm.CmdError:
536536
free = 0
537-
# Select chunk size based on free RAM (~10-15% of free RAM)
538-
if free > 256 * 1024:
537+
# Select chunk size based on free RAM
538+
if free > 320 * 1024:
539539
chunk = 32768
540-
elif free > 128 * 1024:
540+
elif free > 192 * 1024:
541541
chunk = 16384
542-
elif free > 64 * 1024:
542+
elif free > 128 * 1024:
543543
chunk = 8192
544-
elif free > 48 * 1024:
544+
elif free > 92 * 1024:
545545
chunk = 4096
546-
elif free > 32 * 1024:
546+
elif free > 64 * 1024:
547547
chunk = 2048
548-
elif free > 24 * 1024:
548+
elif free > 48 * 1024:
549549
chunk = 1024
550-
else:
550+
elif free > 32 * 1024:
551551
chunk = 512
552+
else:
553+
chunk = 256
552554
Mpy._CHUNK_AUTO_DETECTED = chunk
553555
return chunk
554556

@@ -1146,15 +1148,19 @@ def flash_read(self, label=None, progress_callback=None):
11461148
total_size = block_count * block_size
11471149

11481150
total_blocks = (total_size + block_size - 1) // block_size
1149-
chunk_blocks = 8 # 32KB per iteration
1151+
# Use detect_chunk_size() which auto-detects based on free RAM
1152+
chunk_bytes = self.detect_chunk_size()
1153+
chunk_blocks = max(1, chunk_bytes // block_size)
11501154
data = bytearray()
11511155
block_num = 0
11521156

11531157
while block_num < total_blocks:
11541158
blocks_to_read = min(chunk_blocks, total_blocks - block_num)
11551159
bytes_to_read = blocks_to_read * block_size
1160+
# gc.collect() before each chunk to avoid fragmentation on low-RAM devices
11561161
self._mpy_comm.exec(
1157-
f"_buf=bytearray({bytes_to_read}); _dev.readblocks({block_num}, _buf)")
1162+
f"gc.collect(); _buf=bytearray({bytes_to_read}); "
1163+
f"_dev.readblocks({block_num}, _buf)")
11581164
b64_data = self._mpy_comm.exec_eval("repr(ub.b2a_base64(_buf).decode())")
11591165
chunk = base64.b64decode(b64_data)
11601166
data.extend(chunk)

tests/test_integration.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1342,11 +1342,29 @@ def test_02_partition_read_nvs(self):
13421342
break
13431343
if not nvs:
13441344
self.skipTest("No nvs partition found")
1345-
# Read nvs partition
1345+
# Read nvs partition (flash_read uses dynamic chunk size based on RAM)
13461346
data = self.mpy.flash_read(label='nvs')
13471347
self.assertIsInstance(data, bytes)
13481348
self.assertEqual(len(data), nvs['size'])
13491349

1350+
def test_03_partition_read_phy_init(self):
1351+
"""Test reading phy_init partition (4KB, works on low-RAM devices)"""
1352+
if not self.is_esp32:
1353+
self.skipTest("Not an ESP32 device")
1354+
# Find phy_init partition
1355+
info = self.mpy.partitions()
1356+
phy = None
1357+
for p in info['partitions']:
1358+
if p['label'] == 'phy_init':
1359+
phy = p
1360+
break
1361+
if not phy:
1362+
self.skipTest("No phy_init partition found")
1363+
# Read phy_init partition (small enough for low-RAM devices)
1364+
data = self.mpy.flash_read(label='phy_init')
1365+
self.assertIsInstance(data, bytes)
1366+
self.assertEqual(len(data), phy['size'])
1367+
13501368

13511369
@requires_device
13521370
class TestFlashRP2(unittest.TestCase):

tests/test_mpy.py

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -140,57 +140,57 @@ def tearDown(self):
140140
Mpy._CHUNK_AUTO_DETECTED = None
141141

142142
def test_large_ram_uses_32k_chunks(self):
143-
"""Test that devices with >256KB RAM use 32KB chunks"""
144-
self.mpy._mpy_comm.exec_eval.return_value = 300 * 1024 # 300KB
143+
"""Test that devices with >320KB RAM use 32KB chunks"""
144+
self.mpy._mpy_comm.exec_eval.return_value = 350 * 1024 # 350KB
145145
chunk = self.mpy.detect_chunk_size()
146146
self.assertEqual(chunk, 32768)
147147

148148
def test_medium_large_ram_uses_16k_chunks(self):
149-
"""Test that devices with >128KB RAM use 16KB chunks"""
150-
self.mpy._mpy_comm.exec_eval.return_value = 150 * 1024 # 150KB
149+
"""Test that devices with >192KB RAM use 16KB chunks"""
150+
self.mpy._mpy_comm.exec_eval.return_value = 250 * 1024 # 250KB
151151
chunk = self.mpy.detect_chunk_size()
152152
self.assertEqual(chunk, 16384)
153153

154154
def test_medium_ram_uses_8k_chunks(self):
155-
"""Test that devices with >64KB RAM use 8KB chunks"""
156-
self.mpy._mpy_comm.exec_eval.return_value = 80 * 1024 # 80KB
155+
"""Test that devices with >128KB RAM use 8KB chunks"""
156+
self.mpy._mpy_comm.exec_eval.return_value = 150 * 1024 # 150KB
157157
chunk = self.mpy.detect_chunk_size()
158158
self.assertEqual(chunk, 8192)
159159

160160
def test_small_ram_uses_4k_chunks(self):
161-
"""Test that devices with >48KB RAM use 4KB chunks"""
162-
self.mpy._mpy_comm.exec_eval.return_value = 55 * 1024 # 55KB
161+
"""Test that devices with >92KB RAM use 4KB chunks"""
162+
self.mpy._mpy_comm.exec_eval.return_value = 100 * 1024 # 100KB
163163
chunk = self.mpy.detect_chunk_size()
164164
self.assertEqual(chunk, 4096)
165165

166166
def test_smaller_ram_uses_2k_chunks(self):
167-
"""Test that devices with >32KB RAM use 2KB chunks"""
168-
self.mpy._mpy_comm.exec_eval.return_value = 40 * 1024 # 40KB
167+
"""Test that devices with >64KB RAM use 2KB chunks"""
168+
self.mpy._mpy_comm.exec_eval.return_value = 70 * 1024 # 70KB
169169
chunk = self.mpy.detect_chunk_size()
170170
self.assertEqual(chunk, 2048)
171171

172172
def test_small_ram_uses_1k_chunks(self):
173-
"""Test that devices with >24KB RAM use 1KB chunks"""
174-
self.mpy._mpy_comm.exec_eval.return_value = 28 * 1024 # 28KB
173+
"""Test that devices with >48KB RAM use 1KB chunks"""
174+
self.mpy._mpy_comm.exec_eval.return_value = 55 * 1024 # 55KB
175175
chunk = self.mpy.detect_chunk_size()
176176
self.assertEqual(chunk, 1024)
177177

178178
def test_tiny_ram_uses_512_chunks(self):
179-
"""Test that devices with <=24KB RAM use 512B chunks"""
180-
self.mpy._mpy_comm.exec_eval.return_value = 20 * 1024 # 20KB
179+
"""Test that devices with >32KB RAM use 512B chunks"""
180+
self.mpy._mpy_comm.exec_eval.return_value = 40 * 1024 # 40KB
181181
chunk = self.mpy.detect_chunk_size()
182182
self.assertEqual(chunk, 512)
183183

184-
def test_error_defaults_to_512(self):
185-
"""Test that errors default to 512B chunks"""
184+
def test_error_defaults_to_256(self):
185+
"""Test that errors default to 256B chunks"""
186186
from mpytool.mpy_comm import CmdError
187187
self.mpy._mpy_comm.exec_eval.side_effect = CmdError("cmd", b"", b"error")
188188
chunk = self.mpy.detect_chunk_size()
189-
self.assertEqual(chunk, 512)
189+
self.assertEqual(chunk, 256)
190190

191191
def test_caches_result(self):
192192
"""Test that chunk size is cached after first detection"""
193-
self.mpy._mpy_comm.exec_eval.return_value = 300 * 1024 # 300KB
193+
self.mpy._mpy_comm.exec_eval.return_value = 350 * 1024 # 350KB
194194
chunk1 = self.mpy.detect_chunk_size()
195195
# Change return value - should still use cached
196196
self.mpy._mpy_comm.exec_eval.return_value = 20 * 1024 # 20KB
@@ -340,6 +340,7 @@ def setUp(self):
340340
self.mpy = Mpy(self.mock_conn)
341341
self.mpy._mpy_comm = Mock()
342342
self.mpy._platform = 'esp32' # Set platform for partition operations
343+
self.mpy._chunk_size = 4096 # Skip chunk size detection
343344

344345
def test_flash_read_with_label_returns_bytes(self):
345346
"""Test that flash_read with label returns bytes"""

0 commit comments

Comments
 (0)