tests: Add a suite of tests specifically for the pyboard.
In tests/pyb is now a suite of tests that tests the pyb module on the pyboard. They include expected output files because we can't run CPython on the pyboard to compare against. run-tests script has now been updated to allow pyboard tests to be run. Just pass the option --pyboard. This runs all basic, float and pyb tests. Note that float/math-fun.py currently fails because not all math functions are implemented in stmhal/.
This commit is contained in:
parent
baa2afbb58
commit
41f768f3f3
|
@ -0,0 +1,7 @@
|
|||
accel = pyb.Accel()
|
||||
print(accel)
|
||||
accel.x()
|
||||
accel.y()
|
||||
accel.z()
|
||||
accel.tilt()
|
||||
accel.filtered_xyz()
|
|
@ -0,0 +1 @@
|
|||
<Accel>
|
|
@ -0,0 +1,10 @@
|
|||
from pyb import ADC
|
||||
from pyb import Pin
|
||||
|
||||
adc = ADC('X22')
|
||||
print(adc)
|
||||
|
||||
adc.read()
|
||||
|
||||
buf = bytearray(100)
|
||||
adc.read_timed(buf, 500)
|
|
@ -0,0 +1 @@
|
|||
<ADC on X22 channel=13>
|
|
@ -0,0 +1,8 @@
|
|||
dac = pyb.DAC(1)
|
||||
print(dac)
|
||||
dac.noise(100)
|
||||
dac.triangle(100)
|
||||
dac.write(0)
|
||||
dac.write_timed(bytearray(10), 100, mode=pyb.DAC.NORMAL)
|
||||
pyb.delay(20)
|
||||
dac.write(0)
|
|
@ -0,0 +1 @@
|
|||
<DAC>
|
|
@ -0,0 +1,6 @@
|
|||
ext = pyb.ExtInt('X1', pyb.ExtInt.IRQ_RISING, pyb.Pin.PULL_DOWN, lambda l:print('line:', l))
|
||||
ext.disable()
|
||||
ext.enable()
|
||||
print(ext.line())
|
||||
ext.swint()
|
||||
ext.disable()
|
|
@ -0,0 +1,2 @@
|
|||
0
|
||||
line: 0
|
|
@ -0,0 +1,23 @@
|
|||
from pyb import I2C
|
||||
|
||||
i2c = I2C(1)
|
||||
i2c2 = I2C(2)
|
||||
|
||||
i2c.init(I2C.MASTER, baudrate=400000)
|
||||
print(i2c.scan())
|
||||
i2c.deinit()
|
||||
|
||||
# use accelerometer to test i2c bus
|
||||
|
||||
accel_addr = 76
|
||||
|
||||
pyb.Accel() # this will init the bus for us
|
||||
|
||||
print(i2c.scan())
|
||||
print(i2c.is_ready(accel_addr))
|
||||
|
||||
print(i2c.mem_read(1, accel_addr, 7, timeout=500))
|
||||
i2c.mem_write(0, accel_addr, 0, timeout=500)
|
||||
|
||||
i2c.send(7, addr=accel_addr)
|
||||
i2c.recv(1, addr=accel_addr)
|
|
@ -0,0 +1,4 @@
|
|||
[]
|
||||
[76]
|
||||
True
|
||||
b'\x01'
|
|
@ -0,0 +1,28 @@
|
|||
from pyb import LED
|
||||
|
||||
for i in range(4):
|
||||
print(LED(i+1))
|
||||
|
||||
for i in range(4):
|
||||
LED(i+1).on()
|
||||
pyb.delay(10)
|
||||
for i in range(4):
|
||||
LED(i+1).off()
|
||||
pyb.delay(10)
|
||||
for i in range(4):
|
||||
LED(i+1).toggle()
|
||||
pyb.delay(10)
|
||||
for i in range(4):
|
||||
LED(i+1).intensity(0)
|
||||
|
||||
for i in range(256):
|
||||
LED(4).intensity(i)
|
||||
if LED(4).intensity() != i:
|
||||
print('fail', i)
|
||||
pyb.delay(1)
|
||||
for i in range(256):
|
||||
LED(4).intensity(255 - i)
|
||||
pyb.delay(1)
|
||||
|
||||
for i in range(4):
|
||||
LED(i+1).off()
|
|
@ -0,0 +1,4 @@
|
|||
<LED 1>
|
||||
<LED 2>
|
||||
<LED 3>
|
||||
<LED 4>
|
|
@ -0,0 +1,29 @@
|
|||
from pyb import Pin
|
||||
|
||||
p = Pin('X1')
|
||||
print(p)
|
||||
print(p.name())
|
||||
print(p.pin())
|
||||
print(p.port())
|
||||
|
||||
p = Pin('X1', Pin.IN, Pin.PULL_UP)
|
||||
#p = Pin('X1', Pin.IN, pull=Pin.PULL_UP)
|
||||
print(p.value())
|
||||
|
||||
p.init(p.IN, p.PULL_DOWN)
|
||||
#p.init(p.IN, pull=p.PULL_DOWN)
|
||||
print(p.value())
|
||||
|
||||
p.init(p.OUT_PP)
|
||||
p.low()
|
||||
print(p.value())
|
||||
p.high()
|
||||
print(p.value())
|
||||
p.value(0)
|
||||
print(p.value())
|
||||
p.value(1)
|
||||
print(p.value())
|
||||
p.value(False)
|
||||
print(p.value())
|
||||
p.value(True)
|
||||
print(p.value())
|
|
@ -0,0 +1,12 @@
|
|||
<Pin A0>
|
||||
A0
|
||||
0
|
||||
0
|
||||
1
|
||||
0
|
||||
0
|
||||
1
|
||||
0
|
||||
1
|
||||
0
|
||||
1
|
|
@ -0,0 +1,42 @@
|
|||
# basic tests of pyb module
|
||||
|
||||
import pyb
|
||||
|
||||
# test delay
|
||||
|
||||
pyb.delay(-1)
|
||||
pyb.delay(0)
|
||||
pyb.delay(1)
|
||||
|
||||
start = pyb.millis()
|
||||
pyb.delay(17)
|
||||
print((pyb.millis() - start) // 5) # should print 3
|
||||
|
||||
# test udelay
|
||||
|
||||
pyb.udelay(-1)
|
||||
pyb.udelay(0)
|
||||
pyb.udelay(1)
|
||||
|
||||
start = pyb.millis()
|
||||
pyb.udelay(17000)
|
||||
print((pyb.millis() - start) // 5) # should print 3
|
||||
|
||||
# other
|
||||
|
||||
pyb.disable_irq()
|
||||
pyb.enable_irq()
|
||||
|
||||
print(pyb.freq())
|
||||
|
||||
print(pyb.have_cdc())
|
||||
|
||||
pyb.hid((0, 0, 0, 0)) # won't do anything
|
||||
|
||||
pyb.rng()
|
||||
|
||||
pyb.sync()
|
||||
|
||||
print(len(pyb.unique_id()))
|
||||
|
||||
pyb.wfi()
|
|
@ -0,0 +1,5 @@
|
|||
3
|
||||
3
|
||||
(168000000, 168000000, 42000000, 84000000)
|
||||
True
|
||||
12
|
|
@ -0,0 +1,6 @@
|
|||
from pyb import RTC
|
||||
rtc = RTC()
|
||||
print(rtc)
|
||||
rtc.datetime((2014, 1, 1, 1, 0, 0, 0, 0))
|
||||
pyb.delay(1000)
|
||||
print(rtc.datetime()[:7])
|
|
@ -0,0 +1,2 @@
|
|||
<RTC>
|
||||
(2014, 1, 1, 1, 0, 0, 1)
|
|
@ -0,0 +1,16 @@
|
|||
from pyb import Servo
|
||||
|
||||
servo = Servo(1)
|
||||
print(servo)
|
||||
|
||||
servo.angle(0)
|
||||
servo.angle(10, 100)
|
||||
|
||||
servo.speed(-10)
|
||||
servo.speed(10, 100)
|
||||
|
||||
servo.pulse_width(1500)
|
||||
print(servo.pulse_width())
|
||||
|
||||
servo.calibration(630, 2410, 1490, 2460, 2190)
|
||||
print(servo.calibration())
|
|
@ -0,0 +1,3 @@
|
|||
<Servo 1 at 1500us>
|
||||
1500
|
||||
(630, 2410, 1490, 2460, 2190)
|
|
@ -0,0 +1,17 @@
|
|||
from pyb import SPI
|
||||
|
||||
spi = SPI(1)
|
||||
print(spi)
|
||||
|
||||
spi = SPI(1, SPI.MASTER)
|
||||
spi = SPI(1, SPI.MASTER, baudrate=500000)
|
||||
spi = SPI(1, SPI.MASTER, 500000, polarity=1, phase=1, bits=8, firstbit=SPI.MSB, ti=False, crc=None)
|
||||
print(spi)
|
||||
|
||||
spi.init(SPI.SLAVE)
|
||||
print(spi)
|
||||
|
||||
spi.init(SPI.MASTER)
|
||||
spi.send(1, timeout=100)
|
||||
print(spi.recv(1, timeout=100))
|
||||
print(spi.send_recv(1, timeout=100))
|
|
@ -0,0 +1,5 @@
|
|||
SPI(1)
|
||||
SPI(1, SPI.MASTER, baudrate=328125, polarity=1, phase=1, bits=8)
|
||||
SPI(1, SPI.SLAVE, polarity=1, phase=1, bits=8)
|
||||
b'\xff'
|
||||
b'\xff'
|
|
@ -0,0 +1,6 @@
|
|||
from pyb import Switch
|
||||
|
||||
sw = pyb.Switch()
|
||||
print(sw())
|
||||
sw.callback(print)
|
||||
sw.callback(None)
|
|
@ -0,0 +1 @@
|
|||
False
|
|
@ -0,0 +1,28 @@
|
|||
from pyb import Timer
|
||||
|
||||
tim = Timer(4)
|
||||
tim = Timer(4, prescaler=100, period=200)
|
||||
print(tim.prescaler())
|
||||
print(tim.period())
|
||||
tim.prescaler(300)
|
||||
print(tim.prescaler())
|
||||
tim.period(400)
|
||||
print(tim.period())
|
||||
|
||||
tim = Timer(4, freq=1)
|
||||
tim.init(freq=2000)
|
||||
def f(t):
|
||||
print(1)
|
||||
t.callback(None)
|
||||
tim.callback(f)
|
||||
pyb.delay(10)
|
||||
|
||||
# f3 closes over f2.y
|
||||
def f2(x):
|
||||
y = x
|
||||
def f3(t):
|
||||
print(2, y)
|
||||
t.callback(None)
|
||||
return f3
|
||||
tim.callback(f2(3))
|
||||
pyb.delay(10)
|
|
@ -0,0 +1,6 @@
|
|||
100
|
||||
200
|
||||
300
|
||||
400
|
||||
1
|
||||
2 3
|
|
@ -0,0 +1,12 @@
|
|||
from pyb import UART
|
||||
|
||||
uart = UART(1)
|
||||
uart = UART(1, 9600)
|
||||
uart = UART(1, 9600, bits=8, stop=1, parity=None)
|
||||
print(uart)
|
||||
|
||||
uart.init(1200)
|
||||
print(uart)
|
||||
|
||||
uart.any()
|
||||
uart.send(1, timeout=500)
|
|
@ -0,0 +1,2 @@
|
|||
UART(1, baudrate=9600, bits=8, stop=1, parity=None)
|
||||
UART(1, baudrate=1200, bits=8, stop=1, parity=None)
|
|
@ -0,0 +1 @@
|
|||
../tools/pyboard.py
|
158
tests/run-tests
158
tests/run-tests
|
@ -3,6 +3,7 @@
|
|||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import argparse
|
||||
from glob import glob
|
||||
|
||||
# Tests require at least CPython 3.3. If your default python3 executable
|
||||
|
@ -15,82 +16,113 @@ else:
|
|||
CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3')
|
||||
MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../unix/micropython')
|
||||
|
||||
# Set of tests that we shouldn't run under Travis CI
|
||||
skip_travis_tests = set(['basics/memoryerror.py'])
|
||||
|
||||
def rm_f(fname):
|
||||
if os.path.exists(fname):
|
||||
os.remove(fname)
|
||||
|
||||
test_count = 0
|
||||
testcase_count = 0
|
||||
passed_count = 0
|
||||
failed_tests = []
|
||||
tests = []
|
||||
def run_tests(pyb, tests):
|
||||
test_count = 0
|
||||
testcase_count = 0
|
||||
passed_count = 0
|
||||
failed_tests = []
|
||||
|
||||
if not sys.argv[1:]:
|
||||
test_dirs = ('basics', 'float', 'import', 'io', 'misc')
|
||||
tests = sorted(test_file for test_files in (glob('{}/*.py'.format(dir)) for dir in test_dirs) for test_file in test_files)
|
||||
else:
|
||||
tests = sys.argv[1:]
|
||||
running_under_travis = os.getenv('TRAVIS') == 'true'
|
||||
|
||||
test_on_pyboard = False
|
||||
if test_on_pyboard:
|
||||
import pyboard
|
||||
pyb = pyboard.Pyboard('/dev/ttyACM0')
|
||||
pyb.enter_raw_repl()
|
||||
# Set of tests that we shouldn't run under Travis CI
|
||||
skip_travis_tests = set(['basics/memoryerror.py'])
|
||||
|
||||
running_under_travis = os.getenv('TRAVIS') == 'true'
|
||||
for test_file in tests:
|
||||
if running_under_travis and test_file in skip_travis_tests:
|
||||
print("skip ", test_file)
|
||||
continue
|
||||
|
||||
for test_file in tests:
|
||||
if running_under_travis and test_file in skip_travis_tests:
|
||||
print("skip ", test_file)
|
||||
continue
|
||||
# get expected output
|
||||
test_file_expected = test_file + '.exp'
|
||||
if os.path.isfile(test_file_expected):
|
||||
# expected output given by a file, so read that in
|
||||
with open(test_file_expected, 'rb') as f:
|
||||
output_expected = f.read()
|
||||
else:
|
||||
# run CPython to work out expeceted output
|
||||
try:
|
||||
output_expected = subprocess.check_output([CPYTHON3, '-B', test_file])
|
||||
except subprocess.CalledProcessError:
|
||||
output_expected = b'CPYTHON3 CRASH'
|
||||
|
||||
# run CPython
|
||||
try:
|
||||
output_expected = subprocess.check_output([CPYTHON3, '-B', test_file])
|
||||
except subprocess.CalledProcessError:
|
||||
output_expected = b'CPYTHON3 CRASH'
|
||||
# run Micro Python
|
||||
if pyb is None:
|
||||
# run on PC
|
||||
try:
|
||||
output_mupy = subprocess.check_output([MICROPYTHON, '-X', 'emit=bytecode', test_file])
|
||||
except subprocess.CalledProcessError:
|
||||
output_mupy = b'CRASH'
|
||||
else:
|
||||
# run on pyboard
|
||||
pyb.enter_raw_repl()
|
||||
try:
|
||||
output_mupy = pyb.execfile(test_file).replace(b'\r\n', b'\n')
|
||||
except pyboard.PyboardError:
|
||||
output_mupy = b'CRASH'
|
||||
|
||||
# run Micro Python
|
||||
if test_on_pyboard:
|
||||
testcase_count += len(output_expected.splitlines())
|
||||
|
||||
test_basename = os.path.basename(test_file)
|
||||
test_name = os.path.splitext(test_basename)[0]
|
||||
filename_expected = test_basename + ".exp"
|
||||
filename_mupy = test_basename + ".out"
|
||||
|
||||
if output_expected == output_mupy:
|
||||
print("pass ", test_file)
|
||||
passed_count += 1
|
||||
rm_f(filename_expected)
|
||||
rm_f(filename_mupy)
|
||||
else:
|
||||
with open(filename_expected, "w") as f:
|
||||
f.write(str(output_expected, "ascii"))
|
||||
with open(filename_mupy, "w") as f:
|
||||
f.write(str(output_mupy, "ascii"))
|
||||
print("FAIL ", test_file)
|
||||
failed_tests.append(test_name)
|
||||
|
||||
test_count += 1
|
||||
|
||||
print("{} tests performed ({} individual testcases)".format(test_count, testcase_count))
|
||||
print("{} tests passed".format(passed_count))
|
||||
|
||||
if len(failed_tests) > 0:
|
||||
print("{} tests failed: {}".format(len(failed_tests), ' '.join(failed_tests)))
|
||||
return False
|
||||
|
||||
# all tests succeeded
|
||||
return True
|
||||
|
||||
def main():
|
||||
cmd_parser = argparse.ArgumentParser(description='Run tests for Micro Python.')
|
||||
cmd_parser.add_argument('--pyboard', action='store_true', help='run the tests on the pyboard')
|
||||
cmd_parser.add_argument('files', nargs='*', help='input test files')
|
||||
args = cmd_parser.parse_args()
|
||||
|
||||
if args.pyboard:
|
||||
import pyboard
|
||||
pyb = pyboard.Pyboard('/dev/ttyACM0')
|
||||
pyb.enter_raw_repl()
|
||||
try:
|
||||
output_mupy = pyb.execfile(test_file).replace(b'\r\n', b'\n')
|
||||
except pyboard.PyboardError:
|
||||
output_mupy = b'CRASH'
|
||||
else:
|
||||
try:
|
||||
output_mupy = subprocess.check_output([MICROPYTHON, '-X', 'emit=bytecode', test_file])
|
||||
except subprocess.CalledProcessError:
|
||||
output_mupy = b'CRASH'
|
||||
pyb = None
|
||||
|
||||
testcase_count += len(output_expected.splitlines())
|
||||
|
||||
test_basename = os.path.basename(test_file)
|
||||
test_name = os.path.splitext(test_basename)[0]
|
||||
filename_expected = test_basename + ".exp"
|
||||
filename_mupy = test_basename + ".out"
|
||||
|
||||
if output_expected == output_mupy:
|
||||
print("pass ", test_file)
|
||||
passed_count += 1
|
||||
rm_f(filename_expected)
|
||||
rm_f(filename_mupy)
|
||||
if len(args.files) == 0:
|
||||
if pyb is None:
|
||||
# run PC tests
|
||||
test_dirs = ('basics', 'float', 'import', 'io', 'misc')
|
||||
else:
|
||||
# run pyboard tests
|
||||
test_dirs = ('basics', 'float', 'pyb')
|
||||
tests = sorted(test_file for test_files in (glob('{}/*.py'.format(dir)) for dir in test_dirs) for test_file in test_files)
|
||||
else:
|
||||
with open(filename_expected, "w") as f:
|
||||
f.write(str(output_expected, "ascii"))
|
||||
with open(filename_mupy, "w") as f:
|
||||
f.write(str(output_mupy, "ascii"))
|
||||
print("FAIL ", test_file)
|
||||
failed_tests.append(test_name)
|
||||
# tests explicitly given
|
||||
tests = args.files
|
||||
|
||||
test_count += 1
|
||||
if not run_tests(pyb, tests):
|
||||
sys.exit(1)
|
||||
|
||||
print("{} tests performed ({} individual testcases)".format(test_count, testcase_count))
|
||||
print("{} tests passed".format(passed_count))
|
||||
|
||||
if len(failed_tests) > 0:
|
||||
print("{} tests failed: {}".format(len(failed_tests), ' '.join(failed_tests)))
|
||||
sys.exit(1)
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
Loading…
Reference in New Issue