前回着手したMicroPythonのテストですが、とりあえずbasicsテストがパスするようになりました。(未実装によりskipしているものもありますが)
421 tests performed (12506 individual testcases) 421 tests passed 34 tests skipped: builtin_compile builtin_override builtin_pow3 builtin_pow3_intbig builtin_range_binop builtin_round_int builtin_round_intbig bytes_partition class_delattr_setattr class_descriptor class_inplace_op class_notimpl class_reverse_op deque1 deque2 dict_fixed errno1 exception_chain fun_name generator_name io_buffered_writer namedtuple_asdict ordereddict1 ordereddict_eq parser slice_attrs special_methods2 string_center string_partition string_rpartition string_splitlines subclass_native_call subclass_native_init sys_getsizeof
この過程で気付いたことをメモとして残しておきます。
(1)Python3.6が必要
MicroPythonのテストでは、一部のテストケースにおいて正解を生成するためにPython3.6が必要になりますが、私が使っているUbuntu 16.04ではPython3.6は標準ではサポートされていません。
以下のリンクに、新たなリポジトリを指定してPython3.6を導入する方法が書かれています。
16.04 – How do I install Python 3.6 using apt-get? – Ask Ubuntu
software installation – How to install pip for Python 3.6 on Ubuntu 16.10? – Ask Ubuntu
シリアルポート制御用のpyserialモジュールも必要になります。
sudo add-apt-repository ppa:deadsnakes/ppa sudo apt-get update sudo apt-get install python3.6 sudo apt-get install python3.6-venv curl https://bootstrap.pypa.io/get-pip.py | sudo python3.6 sudo python3.6 -m pip install pyserial export MICROPY_CPYTHON3=python3.6
標準のpython3が置き換わるわけではなく、/usr/bin/python3.6が使えるようになります。
そのため、run-testsスクリプトも先頭行を「#! /usr/bin/env python3.6
」と書き換える必要があります。
これで、これまで失敗していた「io_bytesio_ext2.py」「io_write_ext.py」「python36.py」のテストが成功するようになりました。
もともとMicroPythonの出力結果は正しかったのですが、正解を表すexpファイルのほうが正しく生成できていませんでした。
(2)タイムアウトは10秒
テストスクリプトをボード上で走らせて結果を得る場合、タイムアウトはデフォルトで10秒になっています。
これはtests/pyboard.pyの中で以下のように定義されています。
def exec_raw(self, command, timeout=10, data_consumer=None): self.exec_raw_no_follow(command); return self.follow(timeout, data_consumer)
ですが、Raspberry Pi版のMicroPythonではヒープが普通のマイコンの1000倍くらいありますので、一部のテスト(「gc1.py」と「memoryerror.py」)では処理に10秒以上かかってしまいます。
すると、run-testsスクリプトは「MicroPythonがクラッシュした」と判定してしまいますが、実際にはクラッシュしておらず時間がかかっているだけです。
そこで、上記のtimeout=10をtimeout=100に変更することでテストをパスできるようになりました。
(なおmicropython/extreme_exc.pyのテストはさらに重く、timeout=300くらいにする必要があります。つまり5分近くかかるということです。)
(3)IOBaseのテストに標準入出力が必要
一番最後にパスしたテストが、「io_iobase」というテストです。スクリプトは以下のようになっています。
try:
import uio as io
except:
import io
try:
io.IOBase
except AttributeError:
print('SKIP')
raise SystemExit
class MyIO(io.IOBase):
def write(self, buf):
# CPython and uPy pass in different types for buf (str vs bytearray)
print('write', len(buf))
return len(buf)
print('test', file=MyIO())
最後のprint文で、fileというキーワードは知らない、ということでエラーになっていました。
このfileキーワードですが、printの出力を標準出力以外へ出したいときに使います。
この実装はpy/modbuiltins.cの中で
#if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES
という条件が成立する場合のみ有効になっています。
そのため、IOBaseをテストするためにはMICROPY_PY_SYS_STDFILESも有効にする必要があります。
具体的にはmpconfigport.hの中でMICROPY_PY_SYS_STDFILESを1に設定し、かつこの機能をサポートするためにutils/sys_stdio_mphal.cを(Makefileに)追加します。
コメント