micropython: add micropython component

This commit is contained in:
KY-zhang-X
2022-09-29 12:10:37 +08:00
parent 1514f1cb9b
commit dd76146324
2679 changed files with 354110 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
This directory contains network tests which require Internet connection.
Note that these tests are not run as part of the main testsuite and need
to be run seperately (from the main test/ directory):
./run-tests.py net_inet/*.py

View File

@@ -0,0 +1,52 @@
try:
import usocket as socket, sys
except:
import socket, sys
def test_non_existent():
try:
res = socket.getaddrinfo("nonexistent.example.com", 80)
print("getaddrinfo returned", res)
except OSError as e:
print("getaddrinfo raised")
def test_bogus():
try:
res = socket.getaddrinfo("hey.!!$$", 80)
print("getaddrinfo returned", res)
except OSError as e:
print("getaddrinfo raised")
except Exception as e:
print("getaddrinfo raised") # CPython raises UnicodeError!?
def test_ip_addr():
try:
res = socket.getaddrinfo("10.10.10.10", 80)
print("getaddrinfo returned resolutions")
except Exception as e:
print("getaddrinfo raised", e)
def test_0_0_0_0():
try:
res = socket.getaddrinfo("0.0.0.0", 80)
print("getaddrinfo returned resolutions")
except Exception as e:
print("getaddrinfo raised", e)
def test_valid():
try:
res = socket.getaddrinfo("micropython.org", 80)
print("getaddrinfo returned resolutions")
except Exception as e:
print("getaddrinfo raised", e)
test_funs = [n for n in dir() if n.startswith("test_")]
for f in sorted(test_funs):
print("--", f, end=": ")
eval(f + "()")

View File

@@ -0,0 +1,51 @@
# test that socket.connect() on a non-blocking socket raises EINPROGRESS
# and that an immediate write/send/read/recv does the right thing
import sys
try:
import uerrno as errno, usocket as socket, ussl as ssl
except:
import errno, socket, ssl
def test(addr, hostname, block=True):
print("---", hostname or addr)
s = socket.socket()
s.setblocking(block)
try:
s.connect(addr)
print("connected")
except OSError as e:
if e.errno != errno.EINPROGRESS:
raise
print("EINPROGRESS")
try:
if sys.implementation.name == "micropython":
s = ssl.wrap_socket(s, do_handshake=block)
else:
s = ssl.wrap_socket(s, do_handshake_on_connect=block)
print("wrap: True")
except OSError:
print("wrap: error")
if not block:
try:
while s.write(b"0") is None:
pass
except (ValueError, OSError): # CPython raises ValueError, MicroPython raises OSError
print("write: error")
s.close()
if __name__ == "__main__":
# connect to plain HTTP port, oops!
addr = socket.getaddrinfo("micropython.org", 80)[0][-1]
test(addr, None)
# connect to plain HTTP port, oops!
addr = socket.getaddrinfo("micropython.org", 80)[0][-1]
test(addr, None, False)
# connect to server with self-signed cert, oops!
addr = socket.getaddrinfo("test.mosquitto.org", 8883)[0][-1]
test(addr, "test.mosquitto.org")

View File

@@ -0,0 +1,115 @@
try:
import usocket as socket, ussl as ssl, uerrno as errno, sys
except:
import socket, ssl, errno, sys, time, select
def test_one(site, opts):
ai = socket.getaddrinfo(site, 443)
addr = ai[0][-1]
print(addr)
# Connect the raw socket
s = socket.socket()
s.setblocking(False)
try:
s.connect(addr)
raise OSError(-1, "connect blocks")
except OSError as e:
if e.errno != errno.EINPROGRESS:
raise
if sys.implementation.name != "micropython":
# in CPython we have to wait, otherwise wrap_socket is not happy
select.select([], [s], [])
try:
# Wrap with SSL
try:
if sys.implementation.name == "micropython":
s = ssl.wrap_socket(s, do_handshake=False)
else:
s = ssl.wrap_socket(s, do_handshake_on_connect=False)
except OSError as e:
if e.errno != errno.EINPROGRESS:
raise
print("wrapped")
# CPython needs to be told to do the handshake
if sys.implementation.name != "micropython":
while True:
try:
s.do_handshake()
break
except ssl.SSLError as err:
if err.args[0] == ssl.SSL_ERROR_WANT_READ:
select.select([s], [], [])
elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
select.select([], [s], [])
else:
raise
time.sleep(0.1)
# print("shook hands")
# Write HTTP request
out = b"GET / HTTP/1.0\r\nHost: %s\r\n\r\n" % bytes(site, "latin")
while len(out) > 0:
n = s.write(out)
if n is None:
continue
if n > 0:
out = out[n:]
elif n == 0:
raise OSError(-1, "unexpected EOF in write")
print("wrote")
# Read response
resp = b""
while True:
try:
b = s.read(128)
except OSError as err:
if err.errno == 2: # 2=ssl.SSL_ERROR_WANT_READ:
continue
raise
if b is None:
continue
if len(b) > 0:
if len(resp) < 1024:
resp += b
elif len(b) == 0:
break
print("read")
if resp[:7] != b"HTTP/1.":
raise ValueError("response doesn't start with HTTP/1.")
# print(resp)
finally:
s.close()
SITES = [
"google.com",
{"host": "www.google.com"},
"micropython.org",
"pypi.org",
{"host": "api.pushbullet.com", "sni": True},
]
def main():
for site in SITES:
opts = {}
if isinstance(site, dict):
opts = site
site = opts["host"]
try:
test_one(site, opts)
print(site, "ok")
except Exception as e:
print(site, "error")
print("DONE")
main()

View File

@@ -0,0 +1,61 @@
try:
import usocket as _socket
except:
import _socket
try:
import ussl as ssl
except:
import ssl
# CPython only supports server_hostname with SSLContext
ssl = ssl.SSLContext()
def test_one(site, opts):
ai = _socket.getaddrinfo(site, 443)
addr = ai[0][-1]
s = _socket.socket()
try:
s.connect(addr)
if "sni" in opts:
s = ssl.wrap_socket(s, server_hostname=opts["host"])
else:
s = ssl.wrap_socket(s)
s.write(b"GET / HTTP/1.0\r\nHost: %s\r\n\r\n" % bytes(site, "latin"))
resp = s.read(4096)
if resp[:7] != b"HTTP/1.":
raise ValueError("response doesn't start with HTTP/1.")
# print(resp)
finally:
s.close()
SITES = [
"google.com",
"www.google.com",
"micropython.org",
"pypi.org",
{"host": "api.pushbullet.com", "sni": True},
]
def main():
for site in SITES:
opts = {}
if isinstance(site, dict):
opts = site
site = opts["host"]
try:
test_one(site, opts)
print(site, "ok")
except Exception as e:
print(site, e)
main()

View File

@@ -0,0 +1,5 @@
google.com ok
www.google.com ok
micropython.org ok
pypi.org ok
api.pushbullet.com ok

View File

@@ -0,0 +1,44 @@
# test that modtls produces a numerical error message when out of heap
try:
import usocket as socket, ussl as ssl, sys
except:
import socket, ssl, sys
try:
from micropython import alloc_emergency_exception_buf, heap_lock, heap_unlock
except:
print("SKIP")
raise SystemExit
# test with heap locked to see it switch to number-only error message
def test(addr):
alloc_emergency_exception_buf(256)
s = socket.socket()
s.connect(addr)
try:
s.setblocking(False)
s = ssl.wrap_socket(s, do_handshake=False)
heap_lock()
print("heap is locked")
while True:
ret = s.write("foo")
if ret:
break
heap_unlock()
print("wrap: no exception")
except OSError as e:
heap_unlock()
# mbedtls produces "-29184"
# axtls produces "RECORD_OVERFLOW"
ok = "-29184" in str(e) or "RECORD_OVERFLOW" in str(e)
print("wrap:", ok)
if not ok:
print("got exception:", e)
s.close()
if __name__ == "__main__":
# connect to plain HTTP port, oops!
addr = socket.getaddrinfo("micropython.org", 80)[0][-1]
test(addr)

View File

@@ -0,0 +1,2 @@
heap is locked
wrap: True

View File

@@ -0,0 +1,33 @@
# test that modtls produces a text error message
try:
import usocket as socket, ussl as ssl, sys
except:
import socket, ssl, sys
def test(addr):
s = socket.socket()
s.connect(addr)
try:
s = ssl.wrap_socket(s)
print("wrap: no exception")
except OSError as e:
# mbedtls produces "mbedtls -0x7200: SSL - An invalid SSL record was received"
# axtls produces "RECORD_OVERFLOW" but also prints "TLS buffer overflow,..."
# CPython produces "[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1108)"
ok = (
"SSL_INVALID_RECORD" in str(e)
or "RECORD_OVERFLOW" in str(e)
or "wrong version" in str(e)
)
print("wrap:", ok)
if not ok:
print("got exception:", e)
s.close()
if __name__ == "__main__":
# connect to plain HTTP port, oops!
addr = socket.getaddrinfo("micropython.org", 80)[0][-1]
test(addr)

View File

@@ -0,0 +1,35 @@
# Test cancelling a task waiting on stream IO
try:
import uasyncio as asyncio
except ImportError:
try:
import asyncio
except ImportError:
print("SKIP")
raise SystemExit
async def get(reader):
print("start")
try:
await reader.read(10)
print("fail")
except asyncio.CancelledError:
print("cancelled")
async def main(url):
reader, writer = await asyncio.open_connection(url, 80)
task = asyncio.create_task(get(reader))
await asyncio.sleep(0)
print("cancelling")
task.cancel()
print("waiting")
await task
print("done")
writer.close()
await writer.wait_closed()
asyncio.run(main("micropython.org"))

View File

@@ -0,0 +1,5 @@
start
cancelling
waiting
cancelled
done

View File

@@ -0,0 +1,30 @@
# Test simple HTTP request with uasyncio.open_connection()
try:
import uasyncio as asyncio
except ImportError:
try:
import asyncio
except ImportError:
print("SKIP")
raise SystemExit
async def http_get(url):
reader, writer = await asyncio.open_connection(url, 80)
print("write GET")
writer.write(b"GET / HTTP/1.0\r\n\r\n")
await writer.drain()
print("read response")
data = await reader.read(100)
print("read:", data.split(b"\r\n")[0])
print("close")
writer.close()
await writer.wait_closed()
print("done")
asyncio.run(http_get("micropython.org"))

View File

@@ -0,0 +1,5 @@
write GET
read response
read: b'HTTP/1.1 200 OK'
close
done

View File

@@ -0,0 +1,38 @@
# Test uasyncio.open_connection() and stream readline()
try:
import uasyncio as asyncio
except ImportError:
try:
import asyncio
except ImportError:
print("SKIP")
raise SystemExit
async def http_get_headers(url):
reader, writer = await asyncio.open_connection(url, 80)
print("write GET")
writer.write(b"GET / HTTP/1.0\r\n\r\n")
await writer.drain()
while True:
line = await reader.readline()
line = line.strip()
if not line:
break
if (
line.find(b"Date") == -1
and line.find(b"Modified") == -1
and line.find(b"Server") == -1
):
print(line)
print("close")
writer.close()
await writer.wait_closed()
print("done")
asyncio.run(http_get_headers("micropython.org"))

View File

@@ -0,0 +1,11 @@
write GET
b'HTTP/1.1 200 OK'
b'Content-Type: text/html'
b'Content-Length: 54'
b'Connection: close'
b'Vary: Accept-Encoding'
b'ETag: "54306c85-36"'
b'Strict-Transport-Security: max-age=15768000'
b'Accept-Ranges: bytes'
close
done