From 0b0e0cc2df253e42abffaf04ef5dc5d347f53101 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 16 Jun 2024 10:30:48 +1000 Subject: [PATCH 1/6] quopri: Remove dependency on test.support and subprocess in unit test. Signed-off-by: Damien George --- python-stdlib/quopri/test_quopri.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/python-stdlib/quopri/test_quopri.py b/python-stdlib/quopri/test_quopri.py index 5655dd8b0..b87e54842 100644 --- a/python-stdlib/quopri/test_quopri.py +++ b/python-stdlib/quopri/test_quopri.py @@ -1,7 +1,6 @@ -from test import support import unittest -import sys, os, io, subprocess +import sys, os, io import quopri @@ -193,7 +192,8 @@ def test_decode_header(self): for p, e in self.HSTRINGS: self.assertEqual(quopri.decodestring(e, header=True), p) - def _test_scriptencode(self): + @unittest.skip("requires subprocess") + def test_scriptencode(self): (p, e) = self.STRINGS[-1] process = subprocess.Popen( [sys.executable, "-mquopri"], stdin=subprocess.PIPE, stdout=subprocess.PIPE @@ -210,7 +210,8 @@ def _test_scriptencode(self): self.assertEqual(cout[i], e[i]) self.assertEqual(cout, e) - def _test_scriptdecode(self): + @unittest.skip("requires subprocess") + def test_scriptdecode(self): (p, e) = self.STRINGS[-1] process = subprocess.Popen( [sys.executable, "-mquopri", "-d"], stdin=subprocess.PIPE, stdout=subprocess.PIPE @@ -220,11 +221,3 @@ def _test_scriptdecode(self): cout = cout.decode("latin-1") p = p.decode("latin-1") self.assertEqual(cout.splitlines(), p.splitlines()) - - -def test_main(): - support.run_unittest(QuopriTestCase) - - -if __name__ == "__main__": - test_main() From 469b81b567b9bb81ff6236c40f2959411e9ef1e5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 16 Jun 2024 10:41:05 +1000 Subject: [PATCH 2/6] contextlib: Use a list instead of deque for exit callbacks. Since deque was removed from this repository the built-in one needs to be used, and that doesn't have unbounded growth. So use a list instead, which is adequate becasue contextlib only needs append and pop, not double ended behaviour (the previous pure-Python implementation of deque that was used here anyway used a list as its storage container). Also tweak the excessive-nesting test so it uses less memory and can run on the unix port. Signed-off-by: Damien George --- python-stdlib/contextlib/contextlib.py | 4 ++-- python-stdlib/contextlib/manifest.py | 2 +- python-stdlib/contextlib/tests.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/python-stdlib/contextlib/contextlib.py b/python-stdlib/contextlib/contextlib.py index 2b2020357..3e598b4b6 100644 --- a/python-stdlib/contextlib/contextlib.py +++ b/python-stdlib/contextlib/contextlib.py @@ -85,13 +85,13 @@ class ExitStack(object): """ def __init__(self): - self._exit_callbacks = deque() + self._exit_callbacks = [] def pop_all(self): """Preserve the context stack by transferring it to a new instance""" new_stack = type(self)() new_stack._exit_callbacks = self._exit_callbacks - self._exit_callbacks = deque() + self._exit_callbacks = [] return new_stack def _push_cm_exit(self, cm, cm_exit): diff --git a/python-stdlib/contextlib/manifest.py b/python-stdlib/contextlib/manifest.py index 2894ec5c4..3e05bca18 100644 --- a/python-stdlib/contextlib/manifest.py +++ b/python-stdlib/contextlib/manifest.py @@ -1,4 +1,4 @@ -metadata(description="Port of contextlib for micropython", version="3.4.3") +metadata(description="Port of contextlib for micropython", version="3.4.4") require("ucontextlib") require("collections") diff --git a/python-stdlib/contextlib/tests.py b/python-stdlib/contextlib/tests.py index 19f07add8..c122c452e 100644 --- a/python-stdlib/contextlib/tests.py +++ b/python-stdlib/contextlib/tests.py @@ -399,7 +399,7 @@ def test_exit_exception_chaining_suppress(self): def test_excessive_nesting(self): # The original implementation would die with RecursionError here with ExitStack() as stack: - for i in range(10000): + for i in range(5000): stack.callback(int) def test_instance_bypass(self): From 0d4b3635b4e87bb3a8f36e2e4c0c9198de9963ac Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 16 Jun 2024 10:42:18 +1000 Subject: [PATCH 3/6] datetime: Skip tests that require the host to be in UTC timezone. Signed-off-by: Damien George --- python-stdlib/datetime/test_datetime.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python-stdlib/datetime/test_datetime.py b/python-stdlib/datetime/test_datetime.py index 372bdf3de..98da458f9 100644 --- a/python-stdlib/datetime/test_datetime.py +++ b/python-stdlib/datetime/test_datetime.py @@ -2082,9 +2082,11 @@ def test_timetuple00(self): with LocalTz("Europe/Rome"): self.assertEqual(dt1.timetuple()[:8], (2002, 1, 31, 0, 0, 0, 3, 31)) + @unittest.skip("broken when running with non-UTC timezone") def test_timetuple01(self): self.assertEqual(dt27tz2.timetuple()[:8], (2010, 3, 27, 12, 0, 0, 5, 86)) + @unittest.skip("broken when running with non-UTC timezone") def test_timetuple02(self): self.assertEqual(dt28tz2.timetuple()[:8], (2010, 3, 28, 12, 0, 0, 6, 87)) From f1c7f2885d1da1e0ed07407ff184fd9a9293465a Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 16 Jun 2024 10:42:30 +1000 Subject: [PATCH 4/6] fnmatch: Don't require test.support, which no longer exists. Signed-off-by: Damien George --- python-stdlib/fnmatch/test_fnmatch.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/python-stdlib/fnmatch/test_fnmatch.py b/python-stdlib/fnmatch/test_fnmatch.py index 4eaeec63b..97ef8fff7 100644 --- a/python-stdlib/fnmatch/test_fnmatch.py +++ b/python-stdlib/fnmatch/test_fnmatch.py @@ -1,6 +1,5 @@ """Test cases for the fnmatch module.""" -from test import support import unittest from fnmatch import fnmatch, fnmatchcase, translate, filter @@ -79,11 +78,3 @@ def test_translate(self): class FilterTestCase(unittest.TestCase): def test_filter(self): self.assertEqual(filter(["a", "b"], "a"), ["a"]) - - -def main(): - support.run_unittest(FnmatchTestCase, TranslateTestCase, FilterTestCase) - - -if __name__ == "__main__": - main() From 8834023d05c3fb9467875bda372af3afae2d98e9 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 17 Jun 2024 11:16:53 +1000 Subject: [PATCH 5/6] hashlib: Only import pure Python hashlib when running test. Signed-off-by: Damien George --- python-stdlib/hashlib/tests/test_sha256.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python-stdlib/hashlib/tests/test_sha256.py b/python-stdlib/hashlib/tests/test_sha256.py index 024821b06..a311a8cc9 100644 --- a/python-stdlib/hashlib/tests/test_sha256.py +++ b/python-stdlib/hashlib/tests/test_sha256.py @@ -1,3 +1,7 @@ +# Prevent importing any built-in hashes, so this test tests only the pure Python hashes. +import sys +sys.modules['uhashlib'] = sys + import unittest from hashlib import sha256 From 98f8a7e77181d9558c0080e6a6c9cf920503e4a3 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 14 Jun 2024 11:40:29 +1000 Subject: [PATCH 6/6] github/workflows: Add workflow to run package tests. All of the runable package tests are run together in the new `tools/ci.sh` function called `ci_package_tests_run`. This is added to a new GitHub workflow to test the packages as part of CI. Some packages use `unittest` while others use an ad-hoc test script. Eventually it would be good to unify all the package tests to use `unittest`. Signed-off-by: Damien George --- .github/workflows/package_tests.yml | 16 ++++++ tools/ci.sh | 88 +++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 .github/workflows/package_tests.yml diff --git a/.github/workflows/package_tests.yml b/.github/workflows/package_tests.yml new file mode 100644 index 000000000..5e503509e --- /dev/null +++ b/.github/workflows/package_tests.yml @@ -0,0 +1,16 @@ +name: Package tests + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + - name: Setup environment + run: source tools/ci.sh && ci_package_tests_setup_micropython + - name: Setup libraries + run: source tools/ci.sh && ci_package_tests_setup_lib + - name: Run tests + run: source tools/ci.sh && ci_package_tests_run diff --git a/tools/ci.sh b/tools/ci.sh index 761491c6e..c2cf9dbad 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -1,5 +1,7 @@ #!/bin/bash +CP=/bin/cp + ######################################################################################## # commit formatting @@ -12,6 +14,92 @@ function ci_commit_formatting_run { tools/verifygitlog.py -v upstream/master..HEAD --no-merges } +######################################################################################## +# package tests + +MICROPYTHON=/tmp/micropython/ports/unix/build-standard/micropython + +function ci_package_tests_setup_micropython { + git clone https://github.com/micropython/micropython.git /tmp/micropython + + # build mpy-cross and micropython (use -O0 to speed up the build) + make -C /tmp/micropython/mpy-cross -j CFLAGS_EXTRA=-O0 + make -C /tmp/micropython/ports/unix submodules + make -C /tmp/micropython/ports/unix -j CFLAGS_EXTRA=-O0 +} + +function ci_package_tests_setup_lib { + mkdir -p ~/.micropython/lib + $CP micropython/ucontextlib/ucontextlib.py ~/.micropython/lib/ + $CP python-stdlib/fnmatch/fnmatch.py ~/.micropython/lib/ + $CP -r python-stdlib/hashlib-core/hashlib ~/.micropython/lib/ + $CP -r python-stdlib/hashlib-sha224/hashlib ~/.micropython/lib/ + $CP -r python-stdlib/hashlib-sha256/hashlib ~/.micropython/lib/ + $CP -r python-stdlib/hashlib-sha384/hashlib ~/.micropython/lib/ + $CP -r python-stdlib/hashlib-sha512/hashlib ~/.micropython/lib/ + $CP python-stdlib/shutil/shutil.py ~/.micropython/lib/ + $CP python-stdlib/tempfile/tempfile.py ~/.micropython/lib/ + $CP -r python-stdlib/unittest/unittest ~/.micropython/lib/ + $CP -r python-stdlib/unittest-discover/unittest ~/.micropython/lib/ + $CP unix-ffi/ffilib/ffilib.py ~/.micropython/lib/ + tree ~/.micropython +} + +function ci_package_tests_run { + for test in \ + micropython/drivers/storage/sdcard/sdtest.py \ + micropython/xmltok/test_xmltok.py \ + python-ecosys/requests/test_requests.py \ + python-stdlib/argparse/test_argparse.py \ + python-stdlib/base64/test_base64.py \ + python-stdlib/binascii/test_binascii.py \ + python-stdlib/collections-defaultdict/test_defaultdict.py \ + python-stdlib/functools/test_partial.py \ + python-stdlib/functools/test_reduce.py \ + python-stdlib/heapq/test_heapq.py \ + python-stdlib/hmac/test_hmac.py \ + python-stdlib/itertools/test_itertools.py \ + python-stdlib/operator/test_operator.py \ + python-stdlib/os-path/test_path.py \ + python-stdlib/pickle/test_pickle.py \ + python-stdlib/string/test_translate.py \ + unix-ffi/gettext/test_gettext.py \ + unix-ffi/pwd/test_getpwnam.py \ + unix-ffi/re/test_re.py \ + unix-ffi/time/test_strftime.py \ + ; do + echo "Running test $test" + (cd `dirname $test` && $MICROPYTHON `basename $test`) + if [ $? -ne 0 ]; then + false # make this function return an error code + return + fi + done + + for path in \ + micropython/ucontextlib \ + python-stdlib/contextlib \ + python-stdlib/datetime \ + python-stdlib/fnmatch \ + python-stdlib/hashlib \ + python-stdlib/pathlib \ + python-stdlib/quopri \ + python-stdlib/shutil \ + python-stdlib/tempfile \ + python-stdlib/time \ + python-stdlib/unittest-discover/tests \ + ; do + (cd $path && $MICROPYTHON -m unittest) + if [ $? -ne 0 ]; then false; return; fi + done + + (cd micropython/usb/usb-device && $MICROPYTHON -m tests.test_core_buffer) + if [ $? -ne 0 ]; then false; return; fi + + (cd python-ecosys/cbor2 && $MICROPYTHON -m examples.cbor_test) + if [ $? -ne 0 ]; then false; return; fi +} + ######################################################################################## # build packages