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:
Damien George 2014-05-03 16:43:27 +01:00
parent baa2afbb58
commit 41f768f3f3
30 changed files with 383 additions and 63 deletions

7
tests/pyb/accel.py Normal file
View File

@ -0,0 +1,7 @@
accel = pyb.Accel()
print(accel)
accel.x()
accel.y()
accel.z()
accel.tilt()
accel.filtered_xyz()

1
tests/pyb/accel.py.exp Normal file
View File

@ -0,0 +1 @@
<Accel>

10
tests/pyb/adc.py Normal file
View File

@ -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)

1
tests/pyb/adc.py.exp Normal file
View File

@ -0,0 +1 @@
<ADC on X22 channel=13>

8
tests/pyb/dac.py Normal file
View File

@ -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)

1
tests/pyb/dac.py.exp Normal file
View File

@ -0,0 +1 @@
<DAC>

6
tests/pyb/extint.py Normal file
View File

@ -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()

2
tests/pyb/extint.py.exp Normal file
View File

@ -0,0 +1,2 @@
0
line: 0

23
tests/pyb/i2c.py Normal file
View File

@ -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)

4
tests/pyb/i2c.py.exp Normal file
View File

@ -0,0 +1,4 @@
[]
[76]
True
b'\x01'

28
tests/pyb/led.py Normal file
View File

@ -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()

4
tests/pyb/led.py.exp Normal file
View File

@ -0,0 +1,4 @@
<LED 1>
<LED 2>
<LED 3>
<LED 4>

29
tests/pyb/pin.py Normal file
View File

@ -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())

12
tests/pyb/pin.py.exp Normal file
View File

@ -0,0 +1,12 @@
<Pin A0>
A0
0
0
1
0
0
1
0
1
0
1

42
tests/pyb/pyb1.py Normal file
View File

@ -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()

5
tests/pyb/pyb1.py.exp Normal file
View File

@ -0,0 +1,5 @@
3
3
(168000000, 168000000, 42000000, 84000000)
True
12

6
tests/pyb/rtc.py Normal file
View File

@ -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])

2
tests/pyb/rtc.py.exp Normal file
View File

@ -0,0 +1,2 @@
<RTC>
(2014, 1, 1, 1, 0, 0, 1)

16
tests/pyb/servo.py Normal file
View File

@ -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())

3
tests/pyb/servo.py.exp Normal file
View File

@ -0,0 +1,3 @@
<Servo 1 at 1500us>
1500
(630, 2410, 1490, 2460, 2190)

17
tests/pyb/spi.py Normal file
View File

@ -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))

5
tests/pyb/spi.py.exp Normal file
View File

@ -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'

6
tests/pyb/switch.py Normal file
View File

@ -0,0 +1,6 @@
from pyb import Switch
sw = pyb.Switch()
print(sw())
sw.callback(print)
sw.callback(None)

1
tests/pyb/switch.py.exp Normal file
View File

@ -0,0 +1 @@
False

28
tests/pyb/timer.py Normal file
View File

@ -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)

6
tests/pyb/timer.py.exp Normal file
View File

@ -0,0 +1,6 @@
100
200
300
400
1
2 3

12
tests/pyb/uart.py Normal file
View File

@ -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)

2
tests/pyb/uart.py.exp Normal file
View File

@ -0,0 +1,2 @@
UART(1, baudrate=9600, bits=8, stop=1, parity=None)
UART(1, baudrate=1200, bits=8, stop=1, parity=None)

1
tests/pyboard.py Symbolic link
View File

@ -0,0 +1 @@
../tools/pyboard.py

View File

@ -3,6 +3,7 @@
import os import os
import subprocess import subprocess
import sys import sys
import argparse
from glob import glob from glob import glob
# Tests require at least CPython 3.3. If your default python3 executable # Tests require at least CPython 3.3. If your default python3 executable
@ -15,82 +16,113 @@ else:
CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3') CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3')
MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../unix/micropython') 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): def rm_f(fname):
if os.path.exists(fname): if os.path.exists(fname):
os.remove(fname) os.remove(fname)
test_count = 0 def run_tests(pyb, tests):
testcase_count = 0 test_count = 0
passed_count = 0 testcase_count = 0
failed_tests = [] passed_count = 0
tests = [] failed_tests = []
if not sys.argv[1:]: running_under_travis = os.getenv('TRAVIS') == 'true'
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:]
test_on_pyboard = False # Set of tests that we shouldn't run under Travis CI
if test_on_pyboard: skip_travis_tests = set(['basics/memoryerror.py'])
import pyboard
pyb = pyboard.Pyboard('/dev/ttyACM0')
pyb.enter_raw_repl()
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: # get expected output
if running_under_travis and test_file in skip_travis_tests: test_file_expected = test_file + '.exp'
print("skip ", test_file) if os.path.isfile(test_file_expected):
continue # 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 # run Micro Python
try: if pyb is None:
output_expected = subprocess.check_output([CPYTHON3, '-B', test_file]) # run on PC
except subprocess.CalledProcessError: try:
output_expected = b'CPYTHON3 CRASH' 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 testcase_count += len(output_expected.splitlines())
if test_on_pyboard:
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() 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: else:
try: pyb = None
output_mupy = subprocess.check_output([MICROPYTHON, '-X', 'emit=bytecode', test_file])
except subprocess.CalledProcessError:
output_mupy = b'CRASH'
testcase_count += len(output_expected.splitlines()) if len(args.files) == 0:
if pyb is None:
test_basename = os.path.basename(test_file) # run PC tests
test_name = os.path.splitext(test_basename)[0] test_dirs = ('basics', 'float', 'import', 'io', 'misc')
filename_expected = test_basename + ".exp" else:
filename_mupy = test_basename + ".out" # run pyboard tests
test_dirs = ('basics', 'float', 'pyb')
if output_expected == output_mupy: tests = sorted(test_file for test_files in (glob('{}/*.py'.format(dir)) for dir in test_dirs) for test_file in test_files)
print("pass ", test_file)
passed_count += 1
rm_f(filename_expected)
rm_f(filename_mupy)
else: else:
with open(filename_expected, "w") as f: # tests explicitly given
f.write(str(output_expected, "ascii")) tests = args.files
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 if not run_tests(pyb, tests):
sys.exit(1)
print("{} tests performed ({} individual testcases)".format(test_count, testcase_count)) if __name__ == "__main__":
print("{} tests passed".format(passed_count)) main()
if len(failed_tests) > 0:
print("{} tests failed: {}".format(len(failed_tests), ' '.join(failed_tests)))
sys.exit(1)