diff --git a/ports/esp32/modules/machine.py b/ports/esp32/modules/machine.py index 9cfda12f17753..eecdc14931a1a 100644 --- a/ports/esp32/modules/machine.py +++ b/ports/esp32/modules/machine.py @@ -189,4 +189,7 @@ def phases(self): # Delegate to built-in machine module. def __getattr__(attr): - return getattr(_machine, attr) + value = getattr(_machine, attr, None) + if value is None: + raise ImportError(attr) + return value diff --git a/ports/esp8266/boards/ESP8266_GENERIC/manifest_512kiB.py b/ports/esp8266/boards/ESP8266_GENERIC/manifest_512kiB.py index 15f6cffc3f94a..53538844b4cc6 100644 --- a/ports/esp8266/boards/ESP8266_GENERIC/manifest_512kiB.py +++ b/ports/esp8266/boards/ESP8266_GENERIC/manifest_512kiB.py @@ -1,9 +1,10 @@ module("_boot.py", opt=3) -module("apa102.py", base_path="$(PORT_DIR)/modules", opt=3) -module("port_diag.py", base_path="$(PORT_DIR)/modules", opt=3) -require("ntptime") -require("dht") -require("onewire") -require("ds18x20") -require("webrepl") -require("neopixel") +# module("apa102.py", base_path="$(PORT_DIR)/modules", opt=3) +# module("port_diag.py", base_path="$(PORT_DIR)/modules", opt=3) +# require("ntptime") +# require("dht") +# require("onewire") +# require("ds18x20") +# require("webrepl") +# require("neopixel") +require("unittest") diff --git a/py/objlist.c b/py/objlist.c index 71414a849f40b..ef2262fe9e49c 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -229,8 +229,10 @@ mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg) { mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); if (self->len >= self->alloc) { - self->items = m_renew(mp_obj_t, self->items, self->alloc, self->alloc * 2); - self->alloc *= 2; + // Progression: 4 8 12 20 32 48 72 108 164 248 372 ... + size_t new_alloc = (self->alloc + self->alloc / 2 + 3) & ~3; + self->items = m_renew(mp_obj_t, self->items, self->alloc, new_alloc); + self->alloc = new_alloc; mp_seq_clear(self->items, self->len + 1, self->alloc, sizeof(*self->items)); } self->items[self->len++] = arg; diff --git a/py/persistentcode.h b/py/persistentcode.h index a45d5fd182e5e..15a383c646500 100644 --- a/py/persistentcode.h +++ b/py/persistentcode.h @@ -54,9 +54,9 @@ #define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_X64) #elif MICROPY_EMIT_THUMB #if defined(__thumb2__) - #if defined(__ARM_FP) && (__ARM_FP & 8) == 8 + #if defined(__ARM_FP) && (__ARM_FP & 8) == 8 && defined(__ARM_PCS_VFP) #define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_ARMV7EMDP) - #elif defined(__ARM_FP) && (__ARM_FP & 4) == 4 + #elif defined(__ARM_FP) && (__ARM_FP & 4) == 4 && defined(__ARM_PCS_VFP) #define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_ARMV7EMSP) #else #define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_ARMV7EM) diff --git a/tests/extmod/machine_i2s_rate.py b/tests/extmod/machine_i2s_rate.py index c8fa11514c96b..a38874fa06523 100644 --- a/tests/extmod/machine_i2s_rate.py +++ b/tests/extmod/machine_i2s_rate.py @@ -26,7 +26,10 @@ (2, Pin("D4"), Pin("D3"), Pin("D2"), None), ) elif "esp32" in sys.platform: - i2s_instances = ((0, Pin(18), Pin(19), Pin(21), Pin(14)),) + if "ESP32C3" in sys.implementation._machine or "ESP32-C3" in sys.implementation._machine: + i2s_instances = ((0, Pin(5), Pin(6), Pin(7), Pin(4)),) + else: + i2s_instances = ((0, Pin(18), Pin(19), Pin(21), Pin(14)),) # Allow for small additional RTOS overhead MAX_DELTA_MS = 8 diff --git a/tests/extmod/machine_soft_timer.py b/tests/extmod/machine_soft_timer.py index 1e9c66aa225e1..6f1ff6e58ef1b 100644 --- a/tests/extmod/machine_soft_timer.py +++ b/tests/extmod/machine_soft_timer.py @@ -2,7 +2,7 @@ import sys -if sys.platform in ("esp32", "esp8266"): +if sys.platform in ("esp32", "esp8266", "nrf"): print("SKIP") # TODO: Implement soft timers for esp32/esp8266 ports raise SystemExit diff --git a/tests/extmod/machine_spi_rate.py b/tests/extmod/machine_spi_rate.py index fe15b66fe648a..9a558f46fcbf4 100644 --- a/tests/extmod/machine_spi_rate.py +++ b/tests/extmod/machine_spi_rate.py @@ -16,6 +16,9 @@ if "alif" in sys.platform: MAX_DELTA_MS = 20 spi_instances = ((0, None, None, None),) +elif "samd" in sys.platform: + # Use default SPI instance (tested working on ADAFRUIT_ITSYBITSY_M0_EXPRESS). + spi_instances = ((None, None, None, None),) elif "pyboard" in sys.platform: spi_instances = ( (1, None, None, None), # "explicit choice of sck/mosi/miso is not implemented" @@ -25,13 +28,19 @@ spi_instances = ((0, Pin(18), Pin(19), Pin(16)),) elif "esp32" in sys.platform: impl = str(sys.implementation) - if any(soc in impl for soc in ("ESP32C2", "ESP32C3", "ESP32C6")): - spi_instances = ((1, Pin(4), Pin(5), Pin(6)),) + if any(soc in impl for soc in ("ESP32C2", "ESP32C3", "ESP32-C3", "ESP32C6")): + spi_instances = ((1, None, None, None),) else: - spi_instances = ((1, Pin(18), Pin(19), Pin(21)), (2, Pin(18), Pin(19), Pin(21))) + spi_instances = ((1, None, None, None), (2, None, None, None)) elif "esp8266" in sys.platform: MAX_DELTA_MS = 50 # port requires much looser timing requirements spi_instances = ((1, None, None, None),) # explicit pin choice not allowed +elif "mimxrt" in sys.platform: + # Use default SPI instance (tested working on TEENSY40). + spi_instances = ((None, None, None, None),) +elif "nrf" in sys.platform: + # Tested working on ARDUINO_NANO_33_BLE_SENSE. + spi_instances = ((1, None, None, None),) else: print("Please add support for this test on this platform.") raise SystemExit @@ -111,8 +120,10 @@ def test_spi(spi_id, sck, mosi, miso, baudrate, polarity, phase, print_results): polarity=polarity, phase=phase, ) - else: + elif spi_id is not None: s = SPI(spi_id, baudrate=baudrate, polarity=polarity, phase=phase) + else: + s = SPI(baudrate=baudrate, polarity=polarity, phase=phase) # to keep the test runtime down, use shorter buffer for lower baud rate wr_buf = wr_long if baudrate > 500_000 else wr_short diff --git a/tests/extmod/time_res.py b/tests/extmod/time_res.py index 548bef1f1747c..ef20050b914d7 100644 --- a/tests/extmod/time_res.py +++ b/tests/extmod/time_res.py @@ -37,9 +37,12 @@ def test(): time.sleep_ms(100) for func_name, _ in EXPECTED_MAP: try: - time_func = getattr(time, func_name, None) or globals()[func_name] + if func_name.endswith("_time"): + time_func = globals()[func_name] + else: + time_func = getattr(time, func_name) now = time_func() # may raise AttributeError - except (KeyError, AttributeError): + except AttributeError: continue try: results_map[func_name].add(now) diff --git a/tests/extmod/vfs_blockdev_invalid.py b/tests/extmod/vfs_blockdev_invalid.py index 4d00f4b00273a..78de383784315 100644 --- a/tests/extmod/vfs_blockdev_invalid.py +++ b/tests/extmod/vfs_blockdev_invalid.py @@ -45,6 +45,8 @@ def ioctl(self, op, arg): try: bdev = RAMBlockDevice(50) + vfs.VfsLfs2.mkfs(bdev) + vfs.VfsFat.mkfs(bdev) except MemoryError: print("SKIP") raise SystemExit diff --git a/tests/float/string_format_modulo2_intbig.py b/tests/float/string_format_modulo2_intbig.py index 8110bc7f62e2f..0157c7f44d170 100644 --- a/tests/float/string_format_modulo2_intbig.py +++ b/tests/float/string_format_modulo2_intbig.py @@ -1,5 +1,13 @@ # test formatting floats with large precision, that it doesn't overflow the buffer +try: + import micropython +except: + + class micropython: + def bytecode(f): + return f + def test(num, num_str): if num == float("inf") or num == 0.0 and num_str != "0.0": @@ -18,6 +26,12 @@ def test(num, num_str): # check most powers of 10, making sure to include exponents with 3 digits -for e in range(-101, 102): - num = pow(10, e) - test(num, "1e%d" % e) +# force bytecode emitter so it can feed the WDT on esp8266 +@micropython.bytecode +def main(): + for e in range(-101, 102): + num = pow(10, e) + test(num, "1e%d" % e) + + +main() diff --git a/tests/micropython/ringio_big.py b/tests/micropython/ringio_big.py index d55c4c00b7c0d..198a87a08a5e5 100644 --- a/tests/micropython/ringio_big.py +++ b/tests/micropython/ringio_big.py @@ -8,6 +8,8 @@ print("SKIP") raise SystemExit +result = [] + try: # The maximum possible size micropython.RingIO(bytearray(65535)) @@ -17,13 +19,15 @@ # Buffer may not be too big micropython.RingIO(bytearray(65536)) except ValueError as ex: - print(type(ex)) + result.append(type(ex)) try: # Size may not be too big micropython.RingIO(65535) except ValueError as ex: - print(type(ex)) + result.append(type(ex)) except MemoryError: print("SKIP") raise SystemExit + +print(result) diff --git a/tests/micropython/ringio_big.py.exp b/tests/micropython/ringio_big.py.exp index 72af34b383872..3355e89611958 100644 --- a/tests/micropython/ringio_big.py.exp +++ b/tests/micropython/ringio_big.py.exp @@ -1,2 +1 @@ - - +[, ] diff --git a/tests/misc/rge_sm.py b/tests/misc/rge_sm.py index 56dad5749776e..6084574e70aa6 100644 --- a/tests/misc/rge_sm.py +++ b/tests/misc/rge_sm.py @@ -29,7 +29,7 @@ def iterate(self): k = ktmp[:] step = [s + c * k[ik] for ik, s in enumerate(step)] if self.save: - self.Trajectory += [step] + self.Trajectory.append(step) else: self.Trajectory = [step] return True diff --git a/tests/multi_extmod/machine_i2c_target_irq.py b/tests/multi_extmod/machine_i2c_target_irq.py index eafd9dfdca838..727daf31d71ff 100644 --- a/tests/multi_extmod/machine_i2c_target_irq.py +++ b/tests/multi_extmod/machine_i2c_target_irq.py @@ -15,32 +15,34 @@ print("SKIP") raise SystemExit +from target_wiring import i2c_args, i2c_kwargs + ADDR = 67 clock_stretch_us = 200 # Configure pins based on the target. -if sys.platform == "alif": - i2c_args = (1,) # pins P3_7/P3_6 - i2c_kwargs = {} -elif sys.platform == "mimxrt": - i2c_args = (0,) # pins 19/18 on Teensy 4.x - i2c_kwargs = {} - clock_stretch_us = 50 # mimxrt cannot delay too long in the IRQ handler -elif sys.platform == "rp2": - i2c_args = (0,) - i2c_kwargs = {"scl": 9, "sda": 8} -elif sys.platform == "pyboard": - i2c_args = ("Y",) - i2c_kwargs = {} -elif sys.platform == "samd": - i2c_args = () # pins SCL/SDA - i2c_kwargs = {} -elif "zephyr-rpi_pico" in sys.implementation._machine: - i2c_args = ("i2c1",) # on gpio7/gpio6 - i2c_kwargs = {} -else: - print("Please add support for this test on this platform.") - raise SystemExit +# if sys.platform == "alif": +# i2c_args = (1,) # pins P3_7/P3_6 +# i2c_kwargs = {} +# elif sys.platform == "mimxrt": +# i2c_args = (0,) # pins 19/18 on Teensy 4.x +# i2c_kwargs = {} +# clock_stretch_us = 50 # mimxrt cannot delay too long in the IRQ handler +# elif sys.platform == "rp2": +# i2c_args = (0,) +# i2c_kwargs = {"scl": 9, "sda": 8} +# elif sys.platform == "pyboard": +# i2c_args = ("Y",) +# i2c_kwargs = {} +# elif sys.platform == "samd": +# i2c_args = () # pins SCL/SDA +# i2c_kwargs = {} +# elif "zephyr-rpi_pico" in sys.implementation._machine: +# i2c_args = ("i2c1",) # on gpio7/gpio6 +# i2c_kwargs = {} +# else: +# print("Please add support for this test on this platform.") +# raise SystemExit def simple_irq(i2c_target): diff --git a/tests/multi_extmod/machine_i2c_target_memory.py b/tests/multi_extmod/machine_i2c_target_memory.py index 6b3f0d03eb7fe..8796ec47a34b9 100644 --- a/tests/multi_extmod/machine_i2c_target_memory.py +++ b/tests/multi_extmod/machine_i2c_target_memory.py @@ -10,33 +10,35 @@ import sys from machine import I2C, I2CTarget +from target_wiring import i2c_args, i2c_kwargs + ADDR = 67 -# Configure pins based on the target. -if sys.platform == "alif": - i2c_args = (1,) # pins P3_7/P3_6 - i2c_kwargs = {} -elif sys.platform == "esp32": - i2c_args = (1,) # on pins 9/8 - i2c_kwargs = {} -elif sys.platform == "mimxrt": - i2c_args = (0,) # pins 19/18 on Teensy 4.x - i2c_kwargs = {} -elif sys.platform == "rp2": - i2c_args = (0,) - i2c_kwargs = {"scl": 9, "sda": 8} -elif sys.platform == "pyboard": - i2c_args = ("Y",) - i2c_kwargs = {} -elif sys.platform == "samd": - i2c_args = () # pins SCL/SDA - i2c_kwargs = {} -elif "zephyr-rpi_pico" in sys.implementation._machine: - i2c_args = ("i2c1",) # on gpio7/gpio6 - i2c_kwargs = {} -else: - print("Please add support for this test on this platform.") - raise SystemExit +# # Configure pins based on the target. +# if sys.platform == "alif": +# i2c_args = (1,) # pins P3_7/P3_6 +# i2c_kwargs = {} +# elif sys.platform == "esp32": +# i2c_args = (1,) # on pins 9/8 +# i2c_kwargs = {} +# elif sys.platform == "mimxrt": +# i2c_args = (0,) # pins 19/18 on Teensy 4.x +# i2c_kwargs = {} +# elif sys.platform == "rp2": +# i2c_args = (0,) +# i2c_kwargs = {"scl": 9, "sda": 8} +# elif sys.platform == "pyboard": +# i2c_args = ("Y",) +# i2c_kwargs = {} +# elif sys.platform == "samd": +# i2c_args = () # pins SCL/SDA +# i2c_kwargs = {} +# elif "zephyr-rpi_pico" in sys.implementation._machine: +# i2c_args = ("i2c1",) # on gpio7/gpio6 +# i2c_kwargs = {} +# else: +# print("Please add support for this test on this platform.") +# raise SystemExit def simple_irq(i2c_target): diff --git a/tests/multi_net/asyncio_tls_server_client.py b/tests/multi_net/asyncio_tls_server_client.py index 016f57970c092..335d50bcd0807 100644 --- a/tests/multi_net/asyncio_tls_server_client.py +++ b/tests/multi_net/asyncio_tls_server_client.py @@ -62,5 +62,8 @@ def instance0(): def instance1(): + if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit multitest.next() asyncio.run(tcp_client(b"client data")) diff --git a/tests/multi_net/asyncio_tls_server_client_cert_required_error.py b/tests/multi_net/asyncio_tls_server_client_cert_required_error.py index eac9a98beae6c..5d66d9c1bd95d 100644 --- a/tests/multi_net/asyncio_tls_server_client_cert_required_error.py +++ b/tests/multi_net/asyncio_tls_server_client_cert_required_error.py @@ -8,6 +8,10 @@ print("SKIP") raise SystemExit +if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit + PORT = 8000 # These are test certificates. See tests/README.md for details. diff --git a/tests/multi_net/asyncio_tls_server_client_readline.py b/tests/multi_net/asyncio_tls_server_client_readline.py index 6093628ce5b7b..44797de95ad3a 100644 --- a/tests/multi_net/asyncio_tls_server_client_readline.py +++ b/tests/multi_net/asyncio_tls_server_client_readline.py @@ -66,5 +66,8 @@ def instance0(): def instance1(): + if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit multitest.next() asyncio.run(tcp_client(b"client data\nclient data2\n")) diff --git a/tests/multi_net/asyncio_tls_server_client_verify_error.py b/tests/multi_net/asyncio_tls_server_client_verify_error.py index 6dbff0482c8ae..1ce17585341c9 100644 --- a/tests/multi_net/asyncio_tls_server_client_verify_error.py +++ b/tests/multi_net/asyncio_tls_server_client_verify_error.py @@ -66,5 +66,8 @@ def instance0(): def instance1(): + if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit multitest.next() asyncio.run(tcp_client(b"client data")) diff --git a/tests/multi_net/ssl_cert_ec.py b/tests/multi_net/ssl_cert_ec.py index 8ecbd4d34f6e8..8b487ca367ace 100644 --- a/tests/multi_net/ssl_cert_ec.py +++ b/tests/multi_net/ssl_cert_ec.py @@ -38,6 +38,9 @@ def instance0(): # Client def instance1(): + if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit multitest.next() s = socket.socket() s.connect(socket.getaddrinfo(IP, PORT)[0][-1]) diff --git a/tests/multi_net/ssl_cert_rsa.py b/tests/multi_net/ssl_cert_rsa.py index b99493b0ae5d8..7d3cc08808fb6 100644 --- a/tests/multi_net/ssl_cert_rsa.py +++ b/tests/multi_net/ssl_cert_rsa.py @@ -38,6 +38,9 @@ def instance0(): # Client def instance1(): + if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit multitest.next() s = socket.socket() s.connect(socket.getaddrinfo(IP, PORT)[0][-1]) diff --git a/tests/multi_net/sslcontext_check_hostname_error.py b/tests/multi_net/sslcontext_check_hostname_error.py index 6bd911ddfd7cc..34beba8b66211 100644 --- a/tests/multi_net/sslcontext_check_hostname_error.py +++ b/tests/multi_net/sslcontext_check_hostname_error.py @@ -36,6 +36,9 @@ def instance0(): # Client def instance1(): + if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit multitest.next() s = socket.socket() s.connect(socket.getaddrinfo(IP, PORT)[0][-1]) diff --git a/tests/multi_net/sslcontext_getpeercert.py b/tests/multi_net/sslcontext_getpeercert.py index e2d2a4251163b..82c3b7bafd4c7 100644 --- a/tests/multi_net/sslcontext_getpeercert.py +++ b/tests/multi_net/sslcontext_getpeercert.py @@ -18,6 +18,9 @@ # Server def instance0(): + if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit multitest.globals(IP=multitest.get_network_ip()) s = socket.socket() s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) diff --git a/tests/multi_net/sslcontext_server_client.py b/tests/multi_net/sslcontext_server_client.py index fd330cee78a9c..ed18d8c0c2122 100644 --- a/tests/multi_net/sslcontext_server_client.py +++ b/tests/multi_net/sslcontext_server_client.py @@ -40,6 +40,10 @@ def instance0(): # Client def instance1(): + if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit + multitest.next() s = socket.socket() s.connect(socket.getaddrinfo(IP, PORT)[0][-1]) diff --git a/tests/multi_net/sslcontext_server_client_ciphers.py b/tests/multi_net/sslcontext_server_client_ciphers.py index 7017a6f5798ad..307ee5835a6b0 100644 --- a/tests/multi_net/sslcontext_server_client_ciphers.py +++ b/tests/multi_net/sslcontext_server_client_ciphers.py @@ -41,6 +41,10 @@ def instance0(): # Client def instance1(): + if not hasattr(tls, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit + multitest.next() s = socket.socket() s.connect(socket.getaddrinfo(IP, PORT)[0][-1]) diff --git a/tests/multi_net/sslcontext_server_client_files.py b/tests/multi_net/sslcontext_server_client_files.py index 48ff6376fad9b..1267f43618a98 100644 --- a/tests/multi_net/sslcontext_server_client_files.py +++ b/tests/multi_net/sslcontext_server_client_files.py @@ -35,6 +35,10 @@ def instance0(): # Client def instance1(): + if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit + multitest.next() s = socket.socket() s.connect(socket.getaddrinfo(IP, PORT)[0][-1]) diff --git a/tests/multi_net/sslcontext_verify_callback.py b/tests/multi_net/sslcontext_verify_callback.py index 80056a5868c40..4339b46d85a5d 100644 --- a/tests/multi_net/sslcontext_verify_callback.py +++ b/tests/multi_net/sslcontext_verify_callback.py @@ -28,6 +28,10 @@ def verify_callback(cert, depth): # Server def instance0(): + if not hasattr(tls, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit + multitest.globals(IP=multitest.get_network_ip()) s = socket.socket() s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) diff --git a/tests/multi_net/sslcontext_verify_error.py b/tests/multi_net/sslcontext_verify_error.py index 07dcc690b7ccc..a14d3c3b697bb 100644 --- a/tests/multi_net/sslcontext_verify_error.py +++ b/tests/multi_net/sslcontext_verify_error.py @@ -36,6 +36,10 @@ def instance0(): # Client def instance1(): + if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit + multitest.next() s = socket.socket() s.connect(socket.getaddrinfo(IP, PORT)[0][-1]) diff --git a/tests/multi_net/sslcontext_verify_time_error.py b/tests/multi_net/sslcontext_verify_time_error.py index 7b986322d15bd..a3d4ae1d1ef10 100644 --- a/tests/multi_net/sslcontext_verify_time_error.py +++ b/tests/multi_net/sslcontext_verify_time_error.py @@ -36,6 +36,10 @@ def instance0(): # Client def instance1(): + if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit + multitest.next() s = socket.socket() s.connect(socket.getaddrinfo(IP, PORT)[0][-1]) diff --git a/tests/multi_net/tls_dtls_server_client.py b/tests/multi_net/tls_dtls_server_client.py index ec7d7de55fdc4..10fac3c6f4269 100644 --- a/tests/multi_net/tls_dtls_server_client.py +++ b/tests/multi_net/tls_dtls_server_client.py @@ -7,6 +7,10 @@ print("SKIP") raise SystemExit +if not hasattr(tls, "PROTOCOL_DTLS_SERVER"): + print("SKIP") + raise SystemExit + PORT = 8000 # These are test certificates. See tests/README.md for details. diff --git a/tests/multi_net/udp_data_multi.py b/tests/multi_net/udp_data_multi.py index 5d7b13e5188dd..a2ed33d292d78 100644 --- a/tests/multi_net/udp_data_multi.py +++ b/tests/multi_net/udp_data_multi.py @@ -5,7 +5,7 @@ NUM_NEW_SOCKETS = 4 NUM_PACKET_BURSTS = 6 -NUM_PACKET_GROUPS = 5 +NUM_PACKET_GROUPS = 4 TOTAL_PACKET_BURSTS = NUM_NEW_SOCKETS * NUM_PACKET_BURSTS # The tast passes if more than 75% of packets are received in each group. PACKET_RECV_THRESH = 0.75 * TOTAL_PACKET_BURSTS diff --git a/tests/multi_net/udp_data_multi.py.exp b/tests/multi_net/udp_data_multi.py.exp index bc67c6ab0cf01..a74ef42b7309c 100644 --- a/tests/multi_net/udp_data_multi.py.exp +++ b/tests/multi_net/udp_data_multi.py.exp @@ -7,7 +7,6 @@ pass group=0 pass group=1 pass group=2 pass group=3 -pass group=4 --- instance1 --- test socket 0 test socket 1 diff --git a/tests/net_hosted/ssl_verify_callback.py b/tests/net_hosted/ssl_verify_callback.py index 0dba4e4fddcf6..cd03ff49d77f1 100644 --- a/tests/net_hosted/ssl_verify_callback.py +++ b/tests/net_hosted/ssl_verify_callback.py @@ -4,6 +4,12 @@ import socket import tls +context = tls.SSLContext(tls.PROTOCOL_TLS_CLIENT) + +if not hasattr(context, "verify_callback"): + print("SKIP") + raise SystemExit + def verify_callback(cert, depth): print("verify_callback:", type(cert), len(cert) > 100, depth) @@ -16,7 +22,6 @@ def verify_callback_fail(cert, depth): def test(peer_addr): - context = tls.SSLContext(tls.PROTOCOL_TLS_CLIENT) context.verify_mode = tls.CERT_OPTIONAL context.verify_callback = verify_callback s = socket.socket() diff --git a/tests/net_inet/asyncio_tls_open_connection_readline.py b/tests/net_inet/asyncio_tls_open_connection_readline.py index a0df88be4af1b..492b85a5dbd24 100644 --- a/tests/net_inet/asyncio_tls_open_connection_readline.py +++ b/tests/net_inet/asyncio_tls_open_connection_readline.py @@ -2,6 +2,10 @@ import os import asyncio +if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit + # This certificate was obtained from micropython.org using openssl: # $ openssl s_client -showcerts -connect micropython.org:443 /dev/null # The certificate is from Let's Encrypt: diff --git a/tests/net_inet/mpycert.der b/tests/net_inet/mpycert.der index 0b0eabc9bc813..f583b217ae5d9 100644 Binary files a/tests/net_inet/mpycert.der and b/tests/net_inet/mpycert.der differ diff --git a/tests/net_inet/resolve_on_connect.py b/tests/net_inet/resolve_on_connect.py new file mode 100644 index 0000000000000..587104910e48f --- /dev/null +++ b/tests/net_inet/resolve_on_connect.py @@ -0,0 +1,38 @@ +# Test that the socket module performs DNS resolutions on bind and connect +# Only works on the esp32 port at the moment + +import sys + +if sys.implementation.name == "micropython" and sys.platform != "esp32": + print("SKIP") + raise SystemExit + +import socket +import unittest + + +class Test(unittest.TestCase): + def test_bind_resolves_0_0_0_0(self): + s = socket.socket() + s.bind(("0.0.0.0", 31245)) + s.close() + + def test_bind_resolves_localhost(self): + s = socket.socket() + s.bind(("localhost", 31245)) + s.close() + + def test_connect_resolves(self): + s = socket.socket() + s.connect(("micropython.org", 80)) + s.close() + + def test_connect_non_existent(self): + s = socket.socket() + with self.assertRaises(OSError): + s.connect(("nonexistent.example.com", 80)) + s.close() + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/net_inet/ssl_cert.py b/tests/net_inet/ssl_cert.py index 7bb270d5fda7a..7d64236a02832 100644 --- a/tests/net_inet/ssl_cert.py +++ b/tests/net_inet/ssl_cert.py @@ -1,11 +1,14 @@ import socket import ssl +if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit # This certificate was obtained from micropython.org using openssl: # $ openssl s_client -showcerts -connect micropython.org:443 /dev/null # The certificate is from Let's Encrypt: -# 1 s:C=US, O=Let's Encrypt, CN=R11 +# 1 s:C=US, O=Let's Encrypt, CN=R12 # i:C=US, O=Internet Security Research Group, CN=ISRG Root X1 # a:PKEY: RSA, 2048 (bit); sigalg: sha256WithRSAEncryption # v:NotBefore: Mar 13 00:00:00 2024 GMT; NotAfter: Mar 12 23:59:59 2027 GMT @@ -14,39 +17,39 @@ # Then convert to hex format using: for i in range(0,len(data),40):print(data[i:i+40].hex()) ca_cert_chain = bytes.fromhex( - "30820506308202eea0030201020211008a7d3e13d62f30ef2386bd29076b34f8300d06092a864886" + "30820506308202eea003020102021100c212324b70a9b49171dc40f7e285263c300d06092a864886" "f70d01010b0500304f310b300906035504061302555331293027060355040a1320496e7465726e65" "742053656375726974792052657365617263682047726f7570311530130603550403130c49535247" "20526f6f74205831301e170d3234303331333030303030305a170d3237303331323233353935395a" "3033310b300906035504061302555331163014060355040a130d4c6574277320456e637279707431" - "0c300a0603550403130352313130820122300d06092a864886f70d01010105000382010f00308201" - "0a0282010100ba87bc5c1b0039cbca0acdd46710f9013ca54ea561cb26ca52fb1501b7b928f5281e" - "ed27b324183967090c08ece03ab03b770ebdf3e53954410c4eae41d69974de51dbef7bff58bda8b7" - "13f6de31d5f272c9726a0b8374959c4600641499f3b1d922d9cda892aa1c267a3ffeef58057b0895" - "81db710f8efbe33109bb09be504d5f8f91763d5a9d9e83f2e9c466b3e106664348188065a037189a" - "9b843297b1b2bdc4f815009d2788fbe26317966c9b27674bc4db285e69c279f0495ce02450e1c4bc" - "a105ac7b406d00b4c2413fa758b82fc55c9ba5bb099ef1feebb08539fda80aef45c478eb652ac2cf" - "5f3cdee35c4d1bf70b272baa0b4277534f796a1d87d90203010001a381f83081f5300e0603551d0f" + "0c300a0603550403130352313230820122300d06092a864886f70d01010105000382010f00308201" + "0a0282010100da982874adbe94fe3be01ee2e54b75ab2c127feda703327e3697ece8318fa5138d0b" + "992e1ecd01513d4ce5286e095531aaa5225d72f42d07c24d403cdf0123b97837f51a653234e68671" + "9d04ef84085bbd021a99eba601009a73906d8fa207a0d097d3da456181353d14f9c4c05f6adc0b96" + "1ab09fe32aeabd2ad698c79b71ab3b740f3cdbb260be5a4b4e18e9db2a735c8961659efeed3ca6cb" + "4e6fe49ef90046b3ff194d2a63b38e66c6188570c750656f3b74e548830f08585d2d239d5ea3fee8" + "db00a1d2f4e3194df2ee7af6279ee5cd9c2da2f27f9c17adef133739d1b4c82c41d686c0e9ec21f8" + "591b7fb93a7c9f5c019d6204c228bd0aad3cca10ec1b0203010001a381f83081f5300e0603551d0f" "0101ff040403020186301d0603551d250416301406082b0601050507030206082b06010505070301" - "30120603551d130101ff040830060101ff020100301d0603551d0e04160414c5cf46a4eaf4c3c07a" - "6c95c42db05e922f26e3b9301f0603551d2304183016801479b459e67bb6e5e40173800888c81a58" + "30120603551d130101ff040830060101ff020100301d0603551d0e0416041400b529f22d8e6f31e8" + "9b4cad783efadce90cd1d2301f0603551d2304183016801479b459e67bb6e5e40173800888c81a58" "f6e99b6e303206082b0601050507010104263024302206082b060105050730028616687474703a2f" "2f78312e692e6c656e63722e6f72672f30130603551d20040c300a3008060667810c010201302706" "03551d1f0420301e301ca01aa0188616687474703a2f2f78312e632e6c656e63722e6f72672f300d" - "06092a864886f70d01010b050003820201004ee2895d0a031c9038d0f51ff9715cf8c38fb237887a" - "6fb0251fedbeb7d886068ee90984cd72bf81f3fccacf5348edbdf66942d4a5113e35c813b2921d05" - "5fea2ed4d8f849c3adf599969cef26d8e1b4240b48204dfcd354b4a9c621c8e1361bff77642917b9" - "f04bef5deacd79d0bf90bfbe23b290da4aa9483174a9440be1e2f62d8371a4757bd294c10519461c" - "b98ff3c47448252a0de5f5db43e2db939bb919b41f2fdf6a0e8f31d3630fbb29dcdd662c3fb01b67" - "51f8413ce44db9acb8a49c6663f5ab85231dcc53b6ab71aedcc50171da36ee0a182a32fd09317c8f" - "f673e79c9cb54a156a77825acfda8d45fe1f2a6405303e73c2c60cb9d63b634aab4603fe99c04640" - "276063df503a0747d8154a9fea471f995a08620cb66c33084dd738ed482d2e0568ae805def4cdcd8" - "20415f68f1bb5acde30eb00c31879b43de4943e1c8043fd13c1b87453069a8a9720e79121c31d83e" - "2357dda74fa0f01c81d1771f6fd6d2b9a8b3031681394b9f55aed26ae4b3bfeaa5d59f4ba3c9d63b" - "72f34af654ab0cfc38f76080df6e35ca75a154e42fbc6e17c91aa537b5a29abaecf4c075464f77a8" - "e8595691662d6ede2981d6a697055e6445be2cceea644244b0c34fadf0b4dc03ca999b098295820d" - "638a66f91972f8d5b98910e289980935f9a21cbe92732374e99d1fd73b4a9a845810c2f3a7e235ec" - "7e3b45ce3046526bc0c0" + "06092a864886f70d01010b050003820201008f75d009cf6a7648653292deb544c88576f415848c02" + "bf76ebb3f1e2f96e84a85691e1924bf7e1ea0078488f7592e3e4467b1b602b20afa0ce14e5450d6a" + "e05286a4f3da1414a9a95ff16d46f952501740e9e41e7de61558fea98bfceff59e63e066e2c3773b" + "1f01872694ed4010dcb799ecdd57d35c7141ee30200004dc954b5028879992feaa8094b6060814f8" + "1c837e7440c5085a0c4f5cd1849dc4fddb59deee796e234d95f292d498296a5ceb02c142f0f8f54e" + "64207ba8e331c4c06809478bd8b978a0ca4e4abe69242a4b377b51036b3a3f528bb3d4d2ad584e93" + "eecb5f6f0d314948bac43f9f12c9203d11840785b4f8f23823ac710040e77f8d4634826a4ecfe00e" + "635fba699a47091022fe4b48b7917554cb931ee416eb53cf7bde364dbff6b1ebe64ae9333c8d69a2" + "98bea87fa3ab5fb654e84d96a9acf3b05acb1b7a3693249bce5852809f350a5e2dbf749b6226179c" + "9131290bf37fcdc3628b68c777f47f0bfbc659f503664ba6509bd0efa5fc02b4604d034b614fc520" + "078b48b031f5b69cd1c9ad7718dcb2c70fbee04608dee04bdeb9b8b6c716be36693f86684b748113" + "8950c56a7a02acc548a50e7d5d61e4cdd166a075c7055ee889b5631923bb50b490ecc275373e75a6" + "1b83252800214ec0d33acb9ceac08ff75fae51164610af0206eec0b657d40dac8cd8d7a0f3876ec3" + "e2cbe94ed4a17cfd763b" ) diff --git a/tests/net_inet/ssl_errors.py b/tests/net_inet/ssl_errors.py index bc4e5910bccd8..c23f736b09b08 100644 --- a/tests/net_inet/ssl_errors.py +++ b/tests/net_inet/ssl_errors.py @@ -3,6 +3,10 @@ import sys, errno, select, socket, ssl +if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit + def test(addr, hostname, block=True): print("---", hostname) diff --git a/tests/net_inet/test_sslcontext_client.py b/tests/net_inet/test_sslcontext_client.py index 77f68da496a77..bc06dc3c5832a 100644 --- a/tests/net_inet/test_sslcontext_client.py +++ b/tests/net_inet/test_sslcontext_client.py @@ -2,6 +2,10 @@ import socket import ssl +if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit + # This certificate was obtained from micropython.org using openssl: # $ openssl s_client -showcerts -connect micropython.org:443 /dev/null # The certificate is from Let's Encrypt: diff --git a/tests/net_inet/test_tls_nonblock.py b/tests/net_inet/test_tls_nonblock.py index 60af858b1f146..3f9a61413f9cf 100644 --- a/tests/net_inet/test_tls_nonblock.py +++ b/tests/net_inet/test_tls_nonblock.py @@ -1,5 +1,12 @@ import socket, ssl, errno, sys, time, select +# Although this test doesn't need ssl.CERT_REQUIRED, it does require the ssl module +# to support modern ciphers. So exclude the test on axTLS which doesn't have +# CERT_REQUIRED. +if not hasattr(ssl, "CERT_REQUIRED"): + print("SKIP") + raise SystemExit + def test_one(site, opts): ai = socket.getaddrinfo(site, 443, socket.AF_INET) diff --git a/tests/perf_bench/core_import_mpy_multi.py b/tests/perf_bench/core_import_mpy_multi.py index 8affa157fa0c5..3d5f89c8f68f0 100644 --- a/tests/perf_bench/core_import_mpy_multi.py +++ b/tests/perf_bench/core_import_mpy_multi.py @@ -1,8 +1,9 @@ # Test performance of importing an .mpy file many times. -import sys, io, vfs - -if not hasattr(io, "IOBase"): +try: + import sys, vfs + from io import IOBase +except ImportError: print("SKIP") raise SystemExit @@ -26,7 +27,7 @@ def f(): file_data = b'M\x06\x00\x1f\x14\x03\x0etest.py\x00\x0f\x02A\x00\x02f\x00\x0cresult\x00/-5#\x82I\x81{\x81w\x82/\x81\x05\x81\x17Iom\x82\x13\x06arg\x00\x05\x1cthis will be a string object\x00\x06\x1bthis will be a bytes object\x00\n\x07\x05\x0bconst tuple\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\x81\\\x10\n\x01\x89\x07d`T2\x00\x10\x024\x02\x16\x022\x01\x16\x03"\x80{\x16\x04Qc\x02\x81d\x00\x08\x02(DD\x11\x05\x16\x06\x10\x02\x16\x072\x00\x16\x082\x01\x16\t2\x02\x16\nQc\x03`\x1a\x08\x08\x12\x13@\xb1\xb0\x18\x13Qc@\t\x08\t\x12` Qc@\t\x08\n\x12``Qc\x82@ \x0e\x03\x80\x08+)##\x12\x0b\x12\x0c\x12\r\x12\x0e*\x04Y\x12\x0f\x12\x10\x12\x11*\x03Y#\x00\xc0#\x01\xc0#\x02\xc0Qc' -class File(io.IOBase): +class File(IOBase): def __init__(self): self.off = 0 diff --git a/tests/perf_bench/core_import_mpy_single.py b/tests/perf_bench/core_import_mpy_single.py index 4d9aa67bf2f0e..843bdab934d08 100644 --- a/tests/perf_bench/core_import_mpy_single.py +++ b/tests/perf_bench/core_import_mpy_single.py @@ -2,9 +2,10 @@ # The first import of a module will intern strings that don't already exist, and # this test should be representative of what happens in a real application. -import sys, io, vfs - -if not hasattr(io, "IOBase"): +try: + import sys, vfs + from io import IOBase +except ImportError: print("SKIP") raise SystemExit @@ -81,7 +82,7 @@ def f1(): file_data = b"M\x06\x00\x1f\x81=\x1e\x0etest.py\x00\x0f\x04A0\x00\x04A1\x00\x04f0\x00\x04f1\x00\x0cresult\x00/-5\x04a0\x00\x04a1\x00\x04a2\x00\x04a3\x00\x13\x15\x17\x19\x1b\x1d\x1f!#%')+1379;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}\x7f\x81\x01\x81\x03\x81\x05\x81\x07\x81\t\x81\x0b\x81\r\x81\x0f\x81\x11\x81\x13\x81\x15\x81\x17\x81\x19\x81\x1b\x81\x1d\x81\x1f\x81!\x81#\x81%\x81'\x81)\x81+\x81-\x81/\x811\x813\x815\x817\x819\x81;\x81=\x81?\x81A\x81C\x81E\x81G\x81I\x81K\x81M\x81O\x81Q\x81S\x81U\x81W\x81Y\x81[\x81]\x81_\x81a\x81c\x81e\x81g\x81i\x81k\x81m\x81o\x81q\x81s\x81u\x81w\x81y\x81{\x81}\x81\x7f\x82\x01\x82\x03\x82\x05\x82\x07\x82\t\x82\x0b\x82\r\x82\x0f\x82\x11\x82\x13\x82\x15\x82\x17\x82\x19\x82\x1b\x82\x1d\x82\x1f\x82!\x82#\x82%\x82'\x82)\x82+\x82-\x82/\x821\x823\x825\x827\x829\x82;\x82=\x82?\x82A\x82E\x82G\x82I\x82K\nname0\x00\nname1\x00\nname2\x00\nname3\x00\nname4\x00\nname5\x00\nname6\x00\nname7\x00\nname8\x00\nname9\x00$quite_a_long_name0\x00$quite_a_long_name1\x00$quite_a_long_name2\x00$quite_a_long_name3\x00$quite_a_long_name4\x00$quite_a_long_name5\x00$quite_a_long_name6\x00$quite_a_long_name7\x00$quite_a_long_name8\x00$quite_a_long_name9\x00&quite_a_long_name10\x00&quite_a_long_name11\x00\x05\x1ethis will be a string object 0\x00\x05\x1ethis will be a string object 1\x00\x05\x1ethis will be a string object 2\x00\x05\x1ethis will be a string object 3\x00\x05\x1ethis will be a string object 4\x00\x05\x1ethis will be a string object 5\x00\x05\x1ethis will be a string object 6\x00\x05\x1ethis will be a string object 7\x00\x05\x1ethis will be a string object 8\x00\x05\x1ethis will be a string object 9\x00\x06\x1dthis will be a bytes object 0\x00\x06\x1dthis will be a bytes object 1\x00\x06\x1dthis will be a bytes object 2\x00\x06\x1dthis will be a bytes object 3\x00\x06\x1dthis will be a bytes object 4\x00\x06\x1dthis will be a bytes object 5\x00\x06\x1dthis will be a bytes object 6\x00\x06\x1dthis will be a bytes object 7\x00\x06\x1dthis will be a bytes object 8\x00\x06\x1dthis will be a bytes object 9\x00\n\x07\x05\rconst tuple 0\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 1\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 2\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 3\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 4\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 5\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 6\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 7\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 8\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 9\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\x82d\x10\x12\x01i@i@\x84\x18\x84\x1fT2\x00\x10\x024\x02\x16\x02T2\x01\x10\x034\x02\x16\x032\x02\x16\x042\x03\x16\x05\"\x80{\x16\x06Qc\x04\x82\x0c\x00\n\x02($$$\x11\x07\x16\x08\x10\x02\x16\t2\x00\x16\n2\x01\x16\x0b2\x02\x16\x0c2\x03\x16\rQc\x04@\t\x08\n\x81\x0b Qc@\t\x08\x0b\x81\x0b@Qc@\t\x08\x0c\x81\x0b`QcH\t\n\r\x81\x0b` Qc\x82\x14\x00\x0c\x03h`$$$\x11\x07\x16\x08\x10\x03\x16\t2\x00\x16\n2\x01\x16\x0b2\x02\x16\x0c2\x03\x16\rQc\x04H\t\n\n\x81\x0b``QcH\t\n\x0b\x81\x0b\x80\x07QcH\t\n\x0c\x81\x0b\x80\x08QcH\t\n\r\x81\x0b\x80\tQc\xa08P:\x04\x80\x0b13///---997799<\x1f%\x1f\"\x1f%)\x1f\"//\x12\x0e\x12\x0f\x12\x10\x12\x11\x12\x12\x12\x13\x12\x14*\x07Y\x12\x15\x12\x16\x12\x17\x12\x18\x12\x19\x12\x1a\x12\x08\x12\x07*\x08Y\x12\x1b\x12\x1c\x12\t\x12\x1d\x12\x1e\x12\x1f*\x06Y\x12 \x12!\x12\"\x12#\x12$\x12%*\x06Y\x12&\x12'\x12(\x12)\x12*\x12+*\x06Y\x12,\x12-\x12.\x12/\x120*\x05Y\x121\x122\x123\x124\x125*\x05Y\x126\x127\x128\x129\x12:*\x05Y\x12;\x12<\x12=\x12>\x12?\x12@\x12A\x12B\x12C\x12D\x12E*\x0bY\x12F\x12G\x12H\x12I\x12J\x12K\x12L\x12M\x12N\x12O\x12P*\x0bY\x12Q\x12R\x12S\x12T\x12U\x12V\x12W\x12X\x12Y\x12Z*\nY\x12[\x12\\\x12]\x12^\x12_\x12`\x12a\x12b\x12c\x12d*\nY\x12e\x12f\x12g\x12h\x12i\x12j\x12k\x12l\x12m\x12n\x12o*\x0bY\x12p\x12q\x12r\x12s\x12t\x12u\x12v\x12w\x12x\x12y\x12z*\x0bY\x12{\x12|\x12}\x12~\x12\x7f\x12\x81\x00\x12\x81\x01\x12\x81\x02\x12\x81\x03\x12\x81\x04*\nY\x12\x81\x05\x12\x81\x06\x12\x81\x07\x12\x81\x08\x12\x81\t\x12\x81\n\x12\x81\x0b\x12\x81\x0c\x12\x81\r\x12\x81\x0e\x12\x81\x0f*\x0bY\x12\x81\x10\x12\x81\x11\x12\x81\x12\x12\x81\x13\x12\x81\x14\x12\x81\x15\x12\x81\x16\x12\x81\x17\x12\x81\x18\x12\x81\x19*\nY\x12\x81\x1a\x12\x81\x1b\x12\x81\x1c\x12\x81\x1d\x12\x81\x1e\x12\x81\x1f\x12\x81 \x12\x81!\x12\x81\"\x12\x81#\x12\x81$*\x0bY\x12\x81%\x12\x81&*\x02Y\x12\x81'\x12\x81(\x12\x81)\x12\x81*\x12\x81+\x12\x81,\x12\x81-\x12\x81.\x12\x81/\x12\x810*\nY\x12\x811\x12\x812\x12\x813\x12\x814*\x04Y\x12\x815\x12\x816\x12\x817\x12\x818*\x04Y\x12\x819\x12\x81:\x12\x81;\x12\x81<*\x04YQc\x87p\x08@\x05\x80###############################\x00\xc0#\x01\xc0#\x02\xc0#\x03\xc0#\x04\xc0#\x05\xc0#\x06\xc0#\x07\xc0#\x08\xc0#\t\xc0#\n\xc0#\x0b\xc0#\x0c\xc0#\r\xc0#\x0e\xc0#\x0f\xc0#\x10\xc0#\x11\xc0#\x12\xc0#\x13\xc0#\x14\xc0#\x15\xc0#\x16\xc0#\x17\xc0#\x18\xc0#\x19\xc0#\x1a\xc0#\x1b\xc0#\x1c\xc0#\x1d\xc0Qc" -class File(io.IOBase): +class File(IOBase): def __init__(self): self.off = 0 diff --git a/tests/ports/esp32/check_err_str.py b/tests/ports/esp32/check_err_str.py index 055eecf7476ae..382fc27d5378e 100644 --- a/tests/ports/esp32/check_err_str.py +++ b/tests/ports/esp32/check_err_str.py @@ -7,7 +7,7 @@ # try some vanilla OSError to get std error code try: - open("this filedoesnotexist", "r") + open("/this filedoesnotexist", "r") print("FAILED TO RAISE") except OSError as e: print(e) diff --git a/tests/ports/esp32/resolve_on_connect.py b/tests/ports/esp32/resolve_on_connect.py deleted file mode 100644 index e604ce9ca099a..0000000000000 --- a/tests/ports/esp32/resolve_on_connect.py +++ /dev/null @@ -1,56 +0,0 @@ -# Test that the esp32's socket module performs DNS resolutions on bind and connect -import sys - -if sys.implementation.name == "micropython" and sys.platform != "esp32": - print("SKIP") - raise SystemExit - -import socket, sys - - -def test_bind_resolves_0_0_0_0(): - s = socket.socket() - try: - s.bind(("0.0.0.0", 31245)) - print("bind actually bound") - s.close() - except Exception as e: - print("bind raised", e) - - -def test_bind_resolves_localhost(): - s = socket.socket() - try: - s.bind(("localhost", 31245)) - print("bind actually bound") - s.close() - except Exception as e: - print("bind raised", e) - - -def test_connect_resolves(): - s = socket.socket() - try: - s.connect(("micropython.org", 80)) - print("connect actually connected") - s.close() - except Exception as e: - print("connect raised", e) - - -def test_connect_non_existent(): - s = socket.socket() - try: - s.connect(("nonexistent.example.com", 80)) - print("connect actually connected") - s.close() - except OSError as e: - print("connect raised OSError") - except Exception as e: - print("connect raised", e) - - -test_funs = [n for n in dir() if n.startswith("test_")] -for f in sorted(test_funs): - print("--", f, end=": ") - eval(f + "()") diff --git a/tests/ports/stm32/adcall.py b/tests/ports/stm32/adcall.py index 18896c40cb2a3..cf60aad04cc65 100644 --- a/tests/ports/stm32/adcall.py +++ b/tests/ports/stm32/adcall.py @@ -33,10 +33,14 @@ print(type(adc.read_channel(c))) # call special reading functions -print(skip_temp_test or 0 < adc.read_core_temp() < 100) -print(0 < adc.read_core_vbat() < 4) -print(0 < adc.read_core_vref() < 2) -print(0 < adc.read_vref() < 4) +core_temp = adc.read_core_temp() +core_vbat = adc.read_core_vbat() +core_vref = adc.read_core_vref() +vref = adc.read_vref() +print(skip_temp_test or 0 < core_temp < 100 or core_temp) +print(0 < core_vbat < 4 or core_vbat) +print(0 < core_vref < 2 or core_vref) +print(0 < vref < 4 or vref) if sys.implementation._build == "NUCLEO_WB55": # Restore button pin settings. diff --git a/tests/run-multitests.py b/tests/run-multitests.py index e5458ffe0d00c..5ca3a005999f6 100755 --- a/tests/run-multitests.py +++ b/tests/run-multitests.py @@ -8,12 +8,13 @@ # Runs a test suite that relies on two micropython instances/devices # interacting in some way. Typically used to test networking / bluetooth etc. - +from __future__ import annotations import sys, os, time, re, select import argparse import itertools import subprocess import tempfile +import dataclasses run_tests_module = __import__("run-tests") @@ -264,6 +265,9 @@ def run_script(self, script): def start_script(self, script): self.pyb.enter_raw_repl() + if hasattr(self, 'target_wiring_script'): + cmd = "import sys;sys.modules['target_wiring']=__build_class__(lambda:exec(" + repr(self.target_wiring_script) + "),'target_wiring')" + self.pyb.exec_(cmd) self.pyb.exec_raw_no_follow(script) self.finished = False @@ -318,7 +322,7 @@ def trace_instance_output(instance_idx, line): sys.stdout.flush() -def run_test_on_instances(test_file, num_instances, instances): +def run_test_on_instances(test_file, num_instances, instances: tuple[TestInstance, ...]): global trace_t0 trace_t0 = time.time() @@ -336,12 +340,12 @@ def run_test_on_instances(test_file, num_instances, instances): injected_globals += "HOST_IP = '" + get_host_ip() + "'\n" if cmd_args.trace_output: - print("TRACE {}:".format("|".join(str(i) for i in instances))) + print("TRACE {}:".format("|".join(str(i.pyinstance) for i in instances))) # Start all instances running, in order, waiting until they signal they are ready for idx in range(num_instances): append_code = APPEND_CODE_TEMPLATE.format(injected_globals, idx) - instance = instances[idx] + instance = instances[idx].pyinstance instance.start_file(test_file, append=append_code) last_read_time = time.time() while True: @@ -382,7 +386,7 @@ def run_test_on_instances(test_file, num_instances, instances): num_running = 0 num_output = 0 for idx in range(num_instances): - instance = instances[idx] + instance = instances[idx].pyinstance if instance.is_finished(): continue num_running += 1 @@ -412,7 +416,7 @@ def run_test_on_instances(test_file, num_instances, instances): last_read_time[idx] = time.time() if out.startswith("BROADCAST "): - for instance2 in instances: + for instance2 in [i.pyinstance for i in instances]: if instance2 is not instance: instance2.write(bytes(out, "ascii") + b"\r\n") elif out.startswith("OUTPUT_METRIC "): @@ -431,7 +435,7 @@ def run_test_on_instances(test_file, num_instances, instances): # Stop all instances for idx in range(num_instances): - instances[idx].stop() + instances[idx].pyinstance.stop() output_str = "" for idx, lines in enumerate(output): @@ -485,11 +489,11 @@ def print_diff(a, b): os.unlink(b_path) -def run_tests(test_files, instances_truth, instances_test): +def run_tests(test_files, instances_truth, instances_test: tuple[TestInstance, ...]): test_results = [] for test_file, num_instances in test_files: - instances_str = "|".join(str(instances_test[i]) for i in range(num_instances)) + instances_str = "|".join(str(instances_test[i].pyinstance) for i in range(num_instances)) print("{} on {}: ".format(test_file, instances_str), end="") if cmd_args.show_output or cmd_args.trace_output: print() @@ -548,6 +552,20 @@ def run_tests(test_files, instances_truth, instances_test): return test_results +@dataclasses.dataclass +class TestInstance: + pyinstance: PyInstance + tw_source: str + "The pathname to a file in tests/target_wiring" + + @property + def target_wiring_specified(self) -> bool: + return self.tw_source != "" + + def __repr__(self): + return f"{self.pyinstance.device}({self.tw_source})" + + def main(): global cmd_args @@ -585,6 +603,12 @@ def main(): default=run_tests_module.base_path("results"), help="directory for test results", ) + cmd_parser.add_argument( + "--target-wiring", + action="append", + default=[], + help="force the given script to be used as target_wiring.py", + ) cmd_parser.add_argument("files", nargs="+", help="input test files") cmd_args = cmd_parser.parse_args() @@ -596,27 +620,50 @@ def main(): instances_truth = [PyInstanceSubProcess([PYTHON_TRUTH]) for _ in range(max_instances)] - instances_test = [] - for i in cmd_args.test_instance: + # Make sure the count matches: test_instance, target_wiring, instances_test + if len(cmd_args.target_wiring) == 0: + cmd_args.target_wiring = [""] * len(cmd_args.test_instance) + + if len(cmd_args.test_instance) != len(cmd_args.target_wiring): + print( + "The argument count of '--target-wiring' must match '--target-instance'", + file=sys.stderr, + ) + sys.exit(2) + + instances_test: list[TestInstance] = [] + for i, w in zip(cmd_args.test_instance, cmd_args.target_wiring, strict=True): # Each instance arg is ,ENV=VAR,ENV=VAR... i = i.split(",") cmd = i[0] env = i[1:] if cmd.startswith("exec:"): - instances_test.append(PyInstanceSubProcess([cmd[len("exec:") :]], env)) + pyinstance = PyInstanceSubProcess([cmd[len("exec:") :]], env) elif cmd == "unix": - instances_test.append(PyInstanceSubProcess([MICROPYTHON], env)) + pyinstance = PyInstanceSubProcess([MICROPYTHON], env) elif cmd == "cpython": - instances_test.append(PyInstanceSubProcess([CPYTHON3], env)) + pyinstance = PyInstanceSubProcess([CPYTHON3], env) elif cmd == "webassembly" or cmd.startswith("execpty:"): print("unsupported instance string: {}".format(cmd), file=sys.stderr) sys.exit(2) else: device = run_tests_module.convert_device_shortcut_to_real_device(cmd) - instances_test.append(PyInstancePyboard(device)) + pyinstance = PyInstancePyboard(device) + + instances_test.append(TestInstance(pyinstance=pyinstance, tw_source=w)) for _ in range(max_instances - len(instances_test)): - instances_test.append(PyInstanceSubProcess([MICROPYTHON])) + instances_test.append( + TestInstance(pyinstance=PyInstanceSubProcess([MICROPYTHON]), tw_source="") + ) + + for instance in instances_test: + run_tests_module.detect_target_wiring_script2( + pyb=instance.pyinstance, + target_wiring=instance.tw_source, + platform=None, # TODO: correct parameter + build="", # TODO: correct parameter + ) os.makedirs(cmd_args.result_dir, exist_ok=True) all_pass = True @@ -632,7 +679,7 @@ def main(): for i in instances_truth: i.close() for i in instances_test: - i.close() + i.pyinstance.close() if not all_pass: sys.exit(1) diff --git a/tests/run-natmodtests.py b/tests/run-natmodtests.py index 50e8d1272914e..5b58f9a0e2699 100755 --- a/tests/run-natmodtests.py +++ b/tests/run-natmodtests.py @@ -77,6 +77,10 @@ def open(self, path, mode): """ +class TargetError(Exception): + pass + + class TargetSubprocess: def __init__(self, cmd): self.cmd = cmd @@ -97,7 +101,10 @@ def run_script(self, script): class TargetPyboard: def __init__(self, pyb): self.pyb = pyb - self.pyb.enter_raw_repl() + try: + self.pyb.enter_raw_repl(timeout_overall=4) + except pyboard.PyboardError as er: + raise TargetError(str(er)) def close(self): self.pyb.exit_raw_repl() @@ -105,7 +112,7 @@ def close(self): def run_script(self, script): try: - self.pyb.enter_raw_repl() + self.pyb.enter_raw_repl(timeout_overall=4) output = self.pyb.exec_(script) output = output.replace(b"\r\n", b"\n") return output, None @@ -140,6 +147,7 @@ def run_tests(target_truth, target, args, resolved_arch): prelude = args.begin.read() injected_import_hook_code = injected_import_hook_code.replace("{import_prelude}", prelude) + enter_raw_repl_failure_count = 0 test_results = [] for test_file in args.files: # Find supported test @@ -219,6 +227,12 @@ def run_tests(target_truth, target, args, resolved_arch): # Print result print("{:4} {}{}".format(result, test_file, extra)) + if result == "FAIL" and str(error) == "could not enter raw repl": + enter_raw_repl_failure_count += 1 + if enter_raw_repl_failure_count >= 4: + print("Too many enter_raw_repl failures, aborting test run") + break + return test_results @@ -253,17 +267,21 @@ def main(): cmd_parser.add_argument("files", nargs="*", help="input test files") args = cmd_parser.parse_args() - target_truth = TargetSubprocess([CPYTHON3]) + try: + target_truth = TargetSubprocess([CPYTHON3]) - target = run_tests_module.get_test_instance( - args.test_instance, args.baudrate, args.user, args.password - ) - if target is None: - # Use the unix port of MicroPython. - target = TargetSubprocess([MICROPYTHON]) - else: - # Use a remote target. - target = TargetPyboard(target) + target = run_tests_module.get_test_instance( + args.test_instance, args.baudrate, args.user, args.password + ) + if target is None: + # Use the unix port of MicroPython. + target = TargetSubprocess([MICROPYTHON]) + else: + # Use a remote target. + target = TargetPyboard(target) + except TargetError as er: + print("Cannot initialise targets: {}".format(er)) + sys.exit(2) if hasattr(args, "arch") and args.arch is not None: target_arch = args.arch @@ -272,7 +290,7 @@ def main(): target_platform, target_arch, error = detect_architecture(target) if error: print("Cannot run tests: {}".format(error)) - sys.exit(1) + sys.exit(2) target_arch = ARCH_MAPPINGS.get(target_arch, target_arch) if target_platform: diff --git a/tests/run-perfbench.py b/tests/run-perfbench.py index 039d11a36111e..5a185699f4e56 100755 --- a/tests/run-perfbench.py +++ b/tests/run-perfbench.py @@ -97,14 +97,20 @@ def run_benchmarks(args, target, param_n, param_m, n_average, test_list): print(test_file + ": ", end="") # Check if test should be skipped + skip_reason = "" skip = ( skip_complex - and test_file.find("bm_fft") != -1 + and test_file.endswith(("bm_fft.py", "misc_mandel.py")) or skip_native and test_file.find("viper_") != -1 ) + # bm_hexiom is large. Assume a target without complex support + # doesn't have much RAM and also so skip bm_hexiom. + if skip_complex and test_file.find("bm_hexiom") != -1: + skip = True + skip_reason = "too large" if skip: - test_results.append((test_file, "skip", "")) + test_results.append((test_file, "skip", skip_reason)) print("SKIP") continue @@ -165,6 +171,9 @@ def run_benchmarks(args, target, param_n, param_m, n_average, test_list): if error is not None: if error.startswith("SKIP"): test_results.append((test_file, "skip", error)) + elif error.startswith("CRASH:") and error.find("MemoryError:") != -1: + test_results.append((test_file, "skip", "too large")) + error = "SKIP: too large" else: test_results.append((test_file, "fail", error)) print(error) diff --git a/tests/run-tests.py b/tests/run-tests.py index d6eb9a3fbc258..c92dae05ee6c3 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -177,6 +177,18 @@ def open(self, path, mode): "thread/thread_lock3.py", "thread/thread_shared2.py", ), + "samd/armv6m": ( + # Fails timing bounds. + "extmod/time_res.py", + # Require more detailed error messages. + "micropython/emg_exc.py", + "micropython/heapalloc_exc_compressed.py", + "micropython/heapalloc_exc_compressed_emg_exc.py", + "micropython/native_with.py", + "micropython/opt_level_lineno.py", + "micropython/viper_with.py", + "misc/print_exception.py", + ), "webassembly": ( "basics/string_format_modulo.py", # can't print nulls to stdout "basics/string_strip.py", # can't print nulls to stdout @@ -256,7 +268,9 @@ def platform_to_port(platform): def convert_device_shortcut_to_real_device(device): - if device.startswith("a") and device[1:].isdigit(): + if device.startswith("port:"): + return device.split(":", 1)[1] + elif device.startswith("a") and device[1:].isdigit(): return "/dev/ttyACM" + device[1:] elif device.startswith("u") and device[1:].isdigit(): return "/dev/ttyUSB" + device[1:] @@ -267,9 +281,7 @@ def convert_device_shortcut_to_real_device(device): def get_test_instance(test_instance, baudrate, user, password): - if test_instance.startswith("port:"): - _, port = test_instance.split(":", 1) - elif test_instance == "unix": + if test_instance == "unix": return None elif test_instance == "webassembly": return PyboardNodeRunner() @@ -283,7 +295,12 @@ def get_test_instance(test_instance, baudrate, user, password): pyb = pyboard.Pyboard(port, baudrate, user, password) pyboard.Pyboard.run_script_on_remote_target = run_script_on_remote_target - pyb.enter_raw_repl() + try: + pyb.enter_raw_repl() + except pyboard.PyboardError as e: + print("error: could not detect test instance") + print(e) + sys.exit(2) return pyb @@ -291,8 +308,13 @@ def detect_inline_asm_arch(pyb, args): for arch in ("rv32", "thumb", "xtensa"): output = run_feature_check(pyb, args, "inlineasm_{}.py".format(arch)) if output.strip() == arch.encode(): - return arch - return None + arch_flags = None + if arch == "rv32": + output = run_feature_check(pyb, args, "inlineasm_rv32_zba.py") + if output == b"rv32_zba\n": + arch_flags = "zba" + return arch, arch_flags + return None, None def detect_test_platform(pyb, args): @@ -303,7 +325,7 @@ def detect_test_platform(pyb, args): platform, arch, build, thread, float_prec, unicode = str(output, "ascii").strip().split() if arch == "None": arch = None - inlineasm_arch = detect_inline_asm_arch(pyb, args) + inlineasm_arch, arch_flags = detect_inline_asm_arch(pyb, args) if thread == "None": thread = None float_prec = int(float_prec) @@ -311,8 +333,11 @@ def detect_test_platform(pyb, args): args.platform = platform args.arch = arch + args.arch_flags = arch_flags if arch and not args.mpy_cross_flags: args.mpy_cross_flags = "-march=" + arch + if arch_flags: + args.mpy_cross_flags += " -march-flags=" + arch_flags args.inlineasm_arch = inlineasm_arch args.build = build args.thread = thread @@ -334,19 +359,27 @@ def detect_test_platform(pyb, args): def detect_target_wiring_script(pyb, args): + # TODO: How to detect 'platform' and 'build' + detect_target_wiring_script2( + pyb, target_wiring=args.target_wiring, platform=args.platform, build=args.build + ) + + +def detect_target_wiring_script2(pyb, target_wiring, platform, build): tw_data = b"" tw_source = None - if args.target_wiring: + if target_wiring: # A target_wiring path is explicitly provided, so use that. - tw_source = args.target_wiring + tw_source = target_wiring with open(tw_source, "rb") as f: tw_data = f.read() + elif hasattr(pyb, "exec_raw") and pyb.exec_raw("import target_wiring") == (b"", b""): # The board already has a target_wiring module available, so use that. tw_source = "on-device" else: - port = platform_to_port(args.platform) - build = args.build + port = platform_to_port(platform) + build = build tw_board_exact = None tw_board_partial = None tw_port = None @@ -426,14 +459,17 @@ def run_script_on_remote_target(pyb, args, test_file, is_special): return True, script try: - had_crash = False - pyb.enter_raw_repl() + pyb.enter_raw_repl(timeout_overall=4) if test_file.endswith(tests_requiring_target_wiring) and pyb.target_wiring_script: pyb.exec_( "import sys;sys.modules['target_wiring']=__build_class__(lambda:exec(" + repr(pyb.target_wiring_script) + "),'target_wiring')" ) + except pyboard.PyboardError as e: + return True, b"enter_raw_repl failed\n" + + try: output_mupy = pyb.exec_(script, timeout=TEST_TIMEOUT) except pyboard.PyboardError as e: had_crash = True @@ -726,6 +762,7 @@ def run_script_on_remote_target(self, args, test_file, is_special): def run_tests(pyb, tests, args, result_dir, num_threads=1): testcase_count = ThreadSafeCounter() + enter_raw_repl_failure_count = ThreadSafeCounter() test_results = ThreadSafeCounter([]) skip_tests = set() @@ -930,6 +967,8 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): # Skip platform-specific tests. skip_tests.update(platform_tests_to_skip.get(args.platform, ())) + if args.arch is not None: + skip_tests.update(platform_tests_to_skip.get(args.platform + "/" + args.arch, ())) # Some tests are known to fail on 64-bit machines if pyb is None and platform.architecture()[0] == "64bit": @@ -1098,6 +1137,9 @@ def run_one_test(test_file): rm_f(filename_expected) rm_f(filename_mupy) else: + if output_mupy == b"enter_raw_repl failed\n": + extra_info = "enter_raw_repl failed" + enter_raw_repl_failure_count.increment() print("FAIL ", test_file, extra_info) if output_expected is not None: with open(filename_expected, "wb") as f: @@ -1128,10 +1170,13 @@ def run_one_test(test_file): else: for test in tests: run_one_test(test) + if enter_raw_repl_failure_count.value >= 4: + print("Too many enter_raw_repl failures, aborting test run") + break except TestError as er: for line in er.args[0]: print(line) - sys.exit(1) + sys.exit(2) # Return test results. return test_results.value, testcase_count.value @@ -1195,6 +1240,7 @@ def to_json(obj): }, f, default=to_json, + indent=2, ) # Return True only if all tests succeeded. diff --git a/tests/target_wiring/rp2.py b/tests/target_wiring/rp2.py index cb0fa0d626339..b651e7a1b721f 100644 --- a/tests/target_wiring/rp2.py +++ b/tests/target_wiring/rp2.py @@ -5,3 +5,7 @@ uart_loopback_args = (0,) uart_loopback_kwargs = {"tx": "GPIO0", "rx": "GPIO1"} + +i2c_args = (0,) +i2c_kwargs = {"scl": 9, "sda": 8} + diff --git a/tests/target_wiring/rp2_octoprobe_infra.py b/tests/target_wiring/rp2_octoprobe_infra.py new file mode 100644 index 0000000000000..3cdfd7bdb03be --- /dev/null +++ b/tests/target_wiring/rp2_octoprobe_infra.py @@ -0,0 +1,5 @@ +# Target wiring for rp2 on octoprobe tentacle. +# + +i2c_args = (1,) +i2c_kwargs = {"scl": 11, "sda": 10}