From acb9ff51b823c909af388945f8cee996a484b4a2 Mon Sep 17 00:00:00 2001 From: "Vanya A. Sergeev" Date: Fri, 29 May 2020 01:12:40 -0500 Subject: [PATCH] tests: migrate to more verbose and colorized reporting --- tests/asserts.py | 12 --- tests/test.py | 42 +++++++++ tests/test_gpio.py | 186 +++++++++++++++++++-------------------- tests/test_gpio_sysfs.py | 124 +++++++++++++------------- tests/test_i2c.py | 43 ++++----- tests/test_led.py | 62 +++++++------ tests/test_mmio.py | 79 ++++++++--------- tests/test_pwm.py | 122 ++++++++++++------------- tests/test_serial.py | 132 ++++++++++++++------------- tests/test_spi.py | 80 ++++++++--------- 10 files changed, 447 insertions(+), 435 deletions(-) delete mode 100644 tests/asserts.py create mode 100644 tests/test.py diff --git a/tests/asserts.py b/tests/asserts.py deleted file mode 100644 index eea6a29..0000000 --- a/tests/asserts.py +++ /dev/null @@ -1,12 +0,0 @@ -class AssertRaises(object): - def __init__(self, exception_type): - self.exception_type = exception_type - - def __enter__(self): - return self - - def __exit__(self, t, value, traceback): - if isinstance(value, self.exception_type): - return True - - return False diff --git a/tests/test.py b/tests/test.py new file mode 100644 index 0000000..5718b65 --- /dev/null +++ b/tests/test.py @@ -0,0 +1,42 @@ +import inspect + + +STR_OKAY = " [\x1b[1;32m OK \x1b[0m]" +STR_FAIL = " [\x1b[1;31mFAIL\x1b[0m]" + + +def ptest(): + frame = inspect.stack()[1] + function, lineno = frame[3], frame[2] + print("\n\nStarting test {:s}():{:d}".format(function, lineno)) + + +def pokay(msg): + print("{:s} {:s}".format(STR_OKAY, msg)) + + +def passert(name, condition): + frame = inspect.stack()[1] + filename, function, lineno = frame[1].split('/')[-1], frame[3], frame[2] + print("{:s} {:s} {:s}():{:d} {:s}".format(STR_OKAY if condition else STR_FAIL, filename, function, lineno, name)) + assert condition + + +class AssertRaises(object): + def __init__(self, name, exception_type): + self.name = name + self.exception_type = exception_type + + def __enter__(self): + return self + + def __exit__(self, t, value, traceback): + frame = inspect.stack()[1] + filename, function, lineno = frame[1].split('/')[-1], frame[3], frame[2] + + if not isinstance(value, self.exception_type): + print("{:s} {:s} {:s}():{:d} {:s}".format(STR_FAIL, filename, function, lineno, self.name)) + return False + + print("{:s} {:s} {:s}():{:d} {:s}".format(STR_OKAY, filename, function, lineno, self.name)) + return True diff --git a/tests/test_gpio.py b/tests/test_gpio.py index be5b657..d3a18f6 100644 --- a/tests/test_gpio.py +++ b/tests/test_gpio.py @@ -4,7 +4,7 @@ import time import periphery -from .asserts import AssertRaises +from .test import ptest, pokay, passert, AssertRaises if sys.version_info[0] == 3: raw_input = input @@ -19,147 +19,143 @@ def test_arguments(): - print("Starting arguments test...") + ptest() # Invalid open types - with AssertRaises(TypeError): + with AssertRaises("invalid open types", TypeError): periphery.GPIO(1, 1, "in") - with AssertRaises(TypeError): + with AssertRaises("invalid open types", TypeError): periphery.GPIO("abc", 2.3, "in") - with AssertRaises(TypeError): + with AssertRaises("invalid open types", TypeError): periphery.GPIO("abc", 1, 1) # Invalid direction - with AssertRaises(ValueError): + with AssertRaises("invalid direction", ValueError): periphery.GPIO("abc", 1, "blah") - print("Arguments test passed.") - def test_open_close(): - print("Starting open/close test...") + ptest() # Open non-existent GPIO (export should fail with EINVAL) - with AssertRaises(periphery.GPIOError): + with AssertRaises("non-existent GPIO", periphery.GPIOError): periphery.GPIO(path, 9999, "in") # Open legitimate GPIO gpio = periphery.GPIO(path, line_output, "in") - assert gpio.line == line_output - assert gpio.direction == "in" - assert gpio.fd >= 0 - assert gpio.chip_fd >= 0 + passert("property line", gpio.line == line_output) + passert("direction is in", gpio.direction == "in") + passert("fd >= 0", gpio.fd >= 0) + passert("chip_fd >= 0", gpio.chip_fd >= 0) # Check default label - assert gpio.label == "periphery" + passert("property label", gpio.label == "periphery") # Set invalid direction - with AssertRaises(ValueError): + with AssertRaises("set invalid direction", ValueError): gpio.direction = "blah" # Set invalid edge - with AssertRaises(ValueError): + with AssertRaises("set invalid edge", ValueError): gpio.edge = "blah" # Set invalid bias - with AssertRaises(ValueError): + with AssertRaises("set invalid bias", ValueError): gpio.bias = "blah" # Set invalid drive - with AssertRaises(ValueError): + with AssertRaises("set invalid drive", ValueError): gpio.drive = "blah" # Set direction out, check direction out, check value low gpio.direction = "out" - assert gpio.direction == "out" - assert gpio.read() == False + passert("direction is out", gpio.direction == "out") + passert("value is low", gpio.read() == False) # Set direction low, check direction out, check value low gpio.direction = "low" - assert gpio.direction == "out" - assert gpio.read() == False + passert("direction is out", gpio.direction == "out") + passert("value is low", gpio.read() == False) # Set direction high, check direction out, check value high gpio.direction = "high" - assert gpio.direction == "out" - assert gpio.read() == True + passert("direction is out", gpio.direction == "out") + passert("value is high", gpio.read() == True) # Set drive open drain, check drive open drain gpio.drive = "open_drain" - assert gpio.drive == "open_drain" + passert("drive is open drain", gpio.drive == "open_drain") # Set drive open source, check drive open source gpio.drive = "open_source" - assert gpio.drive == "open_source" + passert("drive is open drain", gpio.drive == "open_source") # Set drive default, check drive default gpio.drive = "default" - assert gpio.drive == "default" + passert("drive is default", gpio.drive == "default") # Set inverted true, check inverted true gpio.inverted = True - assert gpio.inverted == True + passert("inverted is True", gpio.inverted == True) # Set inverted false, check inverted false gpio.inverted = False - assert gpio.inverted == False + passert("inverted is False", gpio.inverted == False) # Attempt to set interrupt edge on output GPIO - with AssertRaises(periphery.GPIOError): + with AssertRaises("set interrupt edge on output GPIO", periphery.GPIOError): gpio.edge = "rising" # Attempt to read event on output GPIO - with AssertRaises(periphery.GPIOError): + with AssertRaises("read event on output GPIO", periphery.GPIOError): gpio.read_event() # Set direction in, check direction in gpio.direction = "in" - assert gpio.direction == "in" + passert("direction is in", gpio.direction == "in") # Set edge none, check edge none gpio.edge = "none" - assert gpio.edge == "none" + passert("edge is none", gpio.edge == "none") # Set edge rising, check edge rising gpio.edge = "rising" - assert gpio.edge == "rising" + passert("edge is rising", gpio.edge == "rising") # Set edge falling, check edge falling gpio.edge = "falling" - assert gpio.edge == "falling" + passert("edge is falling", gpio.edge == "falling") # Set edge both, check edge both gpio.edge = "both" - assert gpio.edge == "both" + passert("edge is both", gpio.edge == "both") # Set edge none, check edge none gpio.edge = "none" - assert gpio.edge == "none" + passert("edge is none", gpio.edge == "none") # Set bias pull up, check bias pull up gpio.bias = "pull_up" - assert gpio.bias == "pull_up" + passert("bias is pull up", gpio.bias == "pull_up") # Set bias pull down, check bias pull down gpio.bias = "pull_down" - assert gpio.bias == "pull_down" + passert("bias is pull down", gpio.bias == "pull_down") # Set bias disable, check bias disable gpio.bias = "disable" - assert gpio.bias == "disable" + passert("bias is disable", gpio.bias == "disable") # Set bias default, check bias default gpio.bias = "default" - assert gpio.bias == "default" + passert("bias is default", gpio.bias == "default") # Attempt to set drive on input GPIO - with AssertRaises(periphery.GPIOError): + with AssertRaises("set drive on input GPIO", periphery.GPIOError): gpio.drive = "open_drain" gpio.close() # Open with keyword arguments gpio = periphery.GPIO(path, line_input, "in", edge="rising", bias="default", drive="default", inverted=False, label="test123") - assert gpio.line == line_input - assert gpio.direction == "in" - assert gpio.fd >= 0 - assert gpio.chip_fd >= 0 - assert gpio.edge == "rising" - assert gpio.bias == "default" - assert gpio.drive == "default" - assert gpio.inverted == False - assert gpio.label == "test123" + passert("property line", gpio.line == line_input) + passert("direction is in", gpio.direction == "in") + passert("fd >= 0", gpio.fd >= 0) + passert("chip_fd >= 0", gpio.chip_fd >= 0) + passert("edge is rising", gpio.edge == "rising") + passert("bias is default", gpio.bias == "default") + passert("drive is default", gpio.drive == "default") + passert("inverted is False", gpio.inverted == False) + passert("label is test123", gpio.label == "test123") gpio.close() - print("Open/close test passed.") - def test_loopback(): - print("Starting loopback test...") + ptest() # Open in and out lines gpio_in = periphery.GPIO(path, line_input, "in") @@ -168,12 +164,12 @@ def test_loopback(): # Drive out low, check in low print("Drive out low, check in low") gpio_out.write(False) - assert gpio_in.read() == False + passert("value is False", gpio_in.read() == False) # Drive out high, check in high print("Drive out high, check in high") gpio_out.write(True) - assert gpio_in.read() == True + passert("value is True", gpio_in.read() == True) # Wrapper for running poll() in a thread def threaded_poll(gpio, timeout): @@ -192,11 +188,11 @@ def f(): poll_ret = threaded_poll(gpio_in, 5) time.sleep(0.5) gpio_out.write(False) - assert poll_ret.get() == True - assert gpio_in.read() == False + passert("gpio_in polled True", poll_ret.get() == True) + passert("value is low", gpio_in.read() == False) event = gpio_in.read_event() - assert event.edge == "falling" - assert event.timestamp != 0 + passert("event edge is falling", event.edge == "falling") + passert("event timestamp is non-zero", event.timestamp != 0) # Check poll rising 0 -> 1 interrupt print("Check poll rising 0 -> 1 interrupt") @@ -204,11 +200,11 @@ def f(): poll_ret = threaded_poll(gpio_in, 5) time.sleep(0.5) gpio_out.write(True) - assert poll_ret.get() == True - assert gpio_in.read() == True + passert("gpin_in polled True", poll_ret.get() == True) + passert("value is high", gpio_in.read() == True) event = gpio_in.read_event() - assert event.edge == "rising" - assert event.timestamp != 0 + passert("event edge is rising", event.edge == "rising") + passert("event timestamp is non-zero", event.timestamp != 0) # Set edge to both gpio_in.edge = "both" @@ -218,51 +214,51 @@ def f(): poll_ret = threaded_poll(gpio_in, 5) time.sleep(0.5) gpio_out.write(False) - assert poll_ret.get() == True - assert gpio_in.read() == False + passert("gpio_in polled True", poll_ret.get() == True) + passert("value is low", gpio_in.read() == False) event = gpio_in.read_event() - assert event.edge == "falling" - assert event.timestamp != 0 + passert("event edge is falling", event.edge == "falling") + passert("event timestamp is non-zero", event.timestamp != 0) # Check poll rising 0 -> 1 interrupt print("Check poll rising 0 -> 1 interrupt") poll_ret = threaded_poll(gpio_in, 5) time.sleep(0.5) gpio_out.write(True) - assert poll_ret.get() == True - assert gpio_in.read() == True + passert("gpio_in polled True", poll_ret.get() == True) + passert("value is high", gpio_in.read() == True) event = gpio_in.read_event() - assert event.edge == "rising" - assert event.timestamp != 0 + passert("event edge is rising", event.edge == "rising") + passert("event timestamp is non-zero", event.timestamp != 0) # Check poll timeout print("Check poll timeout") - assert gpio_in.poll(1) == False + passert("gpio_in polled False", gpio_in.poll(1) == False) # Check poll falling 1 -> 0 interrupt with the poll_multiple() API print("Check poll falling 1 -> 0 interrupt with poll_multiple()") gpio_out.write(False) gpios_ready = periphery.GPIO.poll_multiple([gpio_in], 1) - assert gpios_ready == [gpio_in] - assert gpio_in.read() == False + passert("gpios ready is gpio_in", gpios_ready == [gpio_in]) + passert("value is low", gpio_in.read() == False) event = gpio_in.read_event() - assert event.edge == "falling" - assert event.timestamp != 0 + passert("event edge is falling", event.edge == "falling") + passert("event timestamp is non-zero", event.timestamp != 0) # Check poll rising 0 -> 1 interrupt with the poll_multiple() API print("Check poll rising 0 -> 1 interrupt with poll_multiple()") gpio_out.write(True) gpios_ready = periphery.GPIO.poll_multiple([gpio_in], 1) - assert gpios_ready == [gpio_in] - assert gpio_in.read() == True + passert("gpios ready is gpio_in", gpios_ready == [gpio_in]) + passert("value is high", gpio_in.read() == True) event = gpio_in.read_event() - assert event.edge == "rising" - assert event.timestamp != 0 + passert("event edge is rising", event.edge == "rising") + passert("event timestamp is non-zero", event.timestamp != 0) # Check poll timeout print("Check poll timeout with poll_multiple()") gpios_ready = periphery.GPIO.poll_multiple([gpio_in], 1) - assert gpios_ready == [] + passert("gpios ready is empty", gpios_ready == []) gpio_in.close() gpio_out.close() @@ -275,19 +271,17 @@ def f(): print("Check input GPIO reads high with pull-up bias") gpio_in.bias = "pull_up" time.sleep(0.1) - assert gpio_in.read() == True + passert("value is high", gpio_in.read() == True) # Set bias pull-down, check value is low print("Check input GPIO reads low with pull-down bias") gpio_in.bias = "pull_down" time.sleep(0.1) - assert gpio_in.read() == False + passert("value is low", gpio_in.read() == False) gpio_in.close() gpio_out.close() - print("Loopback test passed.") - def test_interactive(): print("Starting interactive test...") @@ -299,24 +293,22 @@ def test_interactive(): # Check tostring print("GPIO description: {}".format(str(gpio))) - assert raw_input("GPIO description looks ok? y/n ") == "y" + passert("interactive success", raw_input("GPIO description looks ok? y/n ") == "y") # Drive GPIO out low gpio.write(False) - assert raw_input("GPIO out is low? y/n ") == "y" + passert("interactive success", raw_input("GPIO out is low? y/n ") == "y") # Drive GPIO out high gpio.write(True) - assert raw_input("GPIO out is high? y/n ") == "y" + passert("interactive success", raw_input("GPIO out is high? y/n ") == "y") # Drive GPIO out low gpio.write(False) - assert raw_input("GPIO out is low? y/n ") == "y" + passert("interactive success", raw_input("GPIO out is low? y/n ") == "y") gpio.close() - print("Interactive test passed.") - if __name__ == "__main__": if os.environ.get("CI") == "true": @@ -342,11 +334,13 @@ def test_interactive(): line_input = int(sys.argv[2]) line_output = int(sys.argv[3]) - print("Starting GPIO tests...") - test_arguments() + pokay("Arguments test passed.") test_open_close() + pokay("Open/close test passed.") test_loopback() + pokay("Loopback test passed.") test_interactive() + pokay("Interactive test passed.") - print("All GPIO tests passed.") + pokay("All tests passed!") diff --git a/tests/test_gpio_sysfs.py b/tests/test_gpio_sysfs.py index c1cbf1c..deacc84 100644 --- a/tests/test_gpio_sysfs.py +++ b/tests/test_gpio_sysfs.py @@ -4,7 +4,7 @@ import time import periphery -from .asserts import AssertRaises +from .test import ptest, pokay, passert, AssertRaises if sys.version_info[0] == 3: raw_input = input @@ -12,108 +12,106 @@ else: import Queue as queue + line_input = None line_output = None def test_arguments(): - print("Starting arguments test...") + ptest() # Invalid open types - with AssertRaises(TypeError): + with AssertRaises("invalid open types", TypeError): periphery.GPIO("abc", "out") - with AssertRaises(TypeError): + with AssertRaises("invalid open types", TypeError): periphery.GPIO(100, 100) # Invalid direction - with AssertRaises(ValueError): + with AssertRaises("invalid direction", ValueError): periphery.GPIO(100, "blah") - print("Arguments test passed.") def test_open_close(): - print("Starting open/close test...") + ptest() # Open non-existent GPIO (export should fail with EINVAL) - with AssertRaises(periphery.GPIOError): + with AssertRaises("non-existent GPIO", periphery.GPIOError): periphery.GPIO(9999, "in") # Open legitimate GPIO gpio = periphery.GPIO(line_output, "in") - assert gpio.line == line_output - assert gpio.direction == "in" - assert gpio.fd >= 0 + passert("property line", gpio.line == line_output) + passert("direction is in", gpio.direction == "in") + passert("fd >= 0", gpio.fd >= 0) # Set invalid direction - with AssertRaises(ValueError): + with AssertRaises("set invalid direction", ValueError): gpio.direction = "blah" # Set invalid edge - with AssertRaises(ValueError): + with AssertRaises("set invalid edge", ValueError): gpio.edge = "blah" # Unsupported property bias - with AssertRaises(NotImplementedError): + with AssertRaises("unsupported property bias", NotImplementedError): _ = gpio.bias - with AssertRaises(NotImplementedError): + with AssertRaises("unsupported property bias", NotImplementedError): gpio.bias = "pull_up" # Unsupported property drive - with AssertRaises(NotImplementedError): + with AssertRaises("unsupported property drive", NotImplementedError): _ = gpio.drive - with AssertRaises(NotImplementedError): + with AssertRaises("unsupported property drive", NotImplementedError): gpio.drive = "open_drain" # Unsupported proprety - with AssertRaises(NotImplementedError): + with AssertRaises("unsupported property chip_fd", NotImplementedError): _ = gpio.chip_fd # Unsupported method - with AssertRaises(NotImplementedError): + with AssertRaises("unsupported method", NotImplementedError): gpio.read_event() # Set direction out, check direction out, check value low gpio.direction = "out" - assert gpio.direction == "out" - assert gpio.read() == False + passert("direction is out", gpio.direction == "out") + passert("value is low", gpio.read() == False) # Set direction low, check direction out, check value low gpio.direction = "low" - assert gpio.direction == "out" - assert gpio.read() == False + passert("direction is out", gpio.direction == "out") + passert("value is low", gpio.read() == False) # Set direction high, check direction out, check value high gpio.direction = "high" - assert gpio.direction == "out" - assert gpio.read() == True + passert("direction is out", gpio.direction == "out") + passert("ivalue is high", gpio.read() == True) # Set inverted true, check inverted gpio.inverted = True - assert gpio.inverted == True + passert("inverted is True", gpio.inverted == True) # Set inverted false, check inverted gpio.inverted = False - assert gpio.inverted == False + passert("inverted is False", gpio.inverted == False) # Set direction in, check direction in gpio.direction = "in" - assert gpio.direction == "in" + passert("direction is in", gpio.direction == "in") # Set edge none, check edge none gpio.edge = "none" - assert gpio.edge == "none" + passert("edge is none", gpio.edge == "none") # Set edge rising, check edge rising gpio.edge = "rising" - assert gpio.edge == "rising" + passert("edge is rising", gpio.edge == "rising") # Set edge falling, check edge falling gpio.edge = "falling" - assert gpio.edge == "falling" + passert("edge is falling", gpio.edge == "falling") # Set edge both, check edge both gpio.edge = "both" - assert gpio.edge == "both" + passert("edge is both", gpio.edge == "both") # Set edge none, check edge none gpio.edge = "none" - assert gpio.edge == "none" + passert("edge is none", gpio.edge == "none") gpio.close() - print("Open/close test passed.") - def test_loopback(): - print("Starting loopback test...") + ptest() # Open in and out lines gpio_in = periphery.GPIO(line_input, "in") @@ -122,12 +120,12 @@ def test_loopback(): # Drive out low, check in low print("Drive out low, check in low") gpio_out.write(False) - assert gpio_in.read() == False + passert("value is low", gpio_in.read() == False) # Drive out high, check in high print("Drive out high, check in high") gpio_out.write(True) - assert gpio_in.read() == True + passert("value is high", gpio_in.read() == True) # Wrapper for running poll() in a thread def threaded_poll(gpio, timeout): @@ -146,8 +144,8 @@ def f(): poll_ret = threaded_poll(gpio_in, 5) time.sleep(0.5) gpio_out.write(False) - assert poll_ret.get() == True - assert gpio_in.read() == False + passert("gpio_in polled True", poll_ret.get() == True) + passert("value is low", gpio_in.read() == False) # Check poll rising 0 -> 1 interrupt print("Check poll rising 0 -> 1 interrupt") @@ -155,8 +153,8 @@ def f(): poll_ret = threaded_poll(gpio_in, 5) time.sleep(0.5) gpio_out.write(True) - assert poll_ret.get() == True - assert gpio_in.read() == True + passert("gpio_in polled True", poll_ret.get() == True) + passert("value is high", gpio_in.read() == True) # Set edge to both gpio_in.edge = "both" @@ -166,48 +164,46 @@ def f(): poll_ret = threaded_poll(gpio_in, 5) time.sleep(0.5) gpio_out.write(False) - assert poll_ret.get() == True - assert gpio_in.read() == False + passert("gpio_in polled True", poll_ret.get() == True) + passert("value is low", gpio_in.read() == False) # Check poll rising 0 -> 1 interrupt print("Check poll rising 0 -> 1 interrupt") poll_ret = threaded_poll(gpio_in, 5) time.sleep(0.5) gpio_out.write(True) - assert poll_ret.get() == True - assert gpio_in.read() == True + passert("gpio_in polled True", poll_ret.get() == True) + passert("value is high", gpio_in.read() == True) # Check poll timeout print("Check poll timeout") - assert gpio_in.poll(1) == False + passert("gpio_in polled False", gpio_in.poll(1) == False) # Check poll falling 1 -> 0 interrupt with the poll_multiple() API print("Check poll falling 1 -> 0 interrupt with poll_multiple()") gpio_out.write(False) gpios_ready = periphery.GPIO.poll_multiple([gpio_in], 1) - assert gpios_ready == [gpio_in] - assert gpio_in.read() == False + passert("gpios ready is gpio_in", gpios_ready == [gpio_in]) + passert("value is low", gpio_in.read() == False) # Check poll rising 0 -> 1 interrupt with the poll_multiple() API print("Check poll rising 0 -> 1 interrupt with poll_multiple()") gpio_out.write(True) gpios_ready = periphery.GPIO.poll_multiple([gpio_in], 1) - assert gpios_ready == [gpio_in] - assert gpio_in.read() == True + passert("gpios ready is gpio_in", gpios_ready == [gpio_in]) + passert("value is high", gpio_in.read() == True) # Check poll timeout print("Check poll timeout with poll_multiple()") gpios_ready = periphery.GPIO.poll_multiple([gpio_in], 1) - assert gpios_ready == [] + passert("gpios ready is empty", gpios_ready == []) gpio_in.close() gpio_out.close() - print("Loopback test passed.") - def test_interactive(): - print("Starting interactive test...") + ptest() gpio = periphery.GPIO(line_output, "out") @@ -216,24 +212,22 @@ def test_interactive(): # Check tostring print("GPIO description: {}".format(str(gpio))) - assert raw_input("GPIO description looks ok? y/n ") == "y" + passert("interactive success", raw_input("GPIO description looks ok? y/n ") == "y") # Drive GPIO out low gpio.write(False) - assert raw_input("GPIO out is low? y/n ") == "y" + passert("interactive success", raw_input("GPIO out is low? y/n ") == "y") # Drive GPIO out high gpio.write(True) - assert raw_input("GPIO out is high? y/n ") == "y" + passert("interactive success", raw_input("GPIO out is high? y/n ") == "y") # Drive GPIO out low gpio.write(False) - assert raw_input("GPIO out is low? y/n ") == "y" + passert("interactive success", raw_input("GPIO out is low? y/n ") == "y") gpio.close() - print("Interactive test passed.") - if __name__ == "__main__": if os.environ.get("CI") == "true": @@ -258,11 +252,13 @@ def test_interactive(): line_input = int(sys.argv[1]) line_output = int(sys.argv[2]) - print("Starting GPIO tests...") - test_arguments() + pokay("Arguments test passed.") test_open_close() + pokay("Open/close test passed.") test_loopback() + pokay("Loopback test passed.") test_interactive() + pokay("Interactive test passed.") - print("All GPIO tests passed.") + pokay("All tests passed!") diff --git a/tests/test_i2c.py b/tests/test_i2c.py index fdb4d03..87c7fb1 100644 --- a/tests/test_i2c.py +++ b/tests/test_i2c.py @@ -1,51 +1,46 @@ import os import sys + import periphery -from .asserts import AssertRaises +from .test import ptest, pokay, passert, AssertRaises if sys.version_info[0] == 3: raw_input = input + i2c_devpath = None def test_arguments(): - print("Starting arguments test...") + ptest() # Open with invalid type - with AssertRaises(TypeError): + with AssertRaises("open invalid type", TypeError): periphery.I2C(123) - print("Arguments test passed.") - def test_open_close(): - print("Starting open/close test...") + ptest() # Open non-existent device - with AssertRaises(periphery.I2CError): + with AssertRaises("non-existent device", periphery.I2CError): periphery.I2C("/foo/bar") # Open legitimate device i2c = periphery.I2C(i2c_devpath) - assert i2c.fd > 0 + passert("fd >= 0", i2c.fd >= 0) # Close I2C i2c.close() - print("Open/close test passed.") - def test_loopback(): - print("Starting loopback test...") - - print("No general way to do a loopback test for I2C without a real component, skipping...") - - print("Loopback test passed.") + ptest() + # No general way to do a loopback test for I2C without a real component, skipping... def test_interactive(): - print("Starting interactive test...") + ptest() # Open device 2 i2c = periphery.I2C(i2c_devpath) @@ -56,7 +51,7 @@ def test_interactive(): # Check tostring print("I2C description: {}".format(str(i2c))) - assert raw_input("I2C description looks ok? y/n ") == "y" + passert("interactive success", raw_input("I2C description looks ok? y/n ") == "y") # There isn't much we can do without assuming a device on the other end, # because I2C needs an acknowledgement bit on each transferred byte. @@ -69,15 +64,13 @@ def test_interactive(): raw_input("Press enter to start transfer...") # Transfer to non-existent device - with AssertRaises(periphery.I2CError): + with AssertRaises("transfer to non-existent device", periphery.I2CError): i2c.transfer(0x7a, messages) i2c.close() success = raw_input("I2C transfer occurred? y/n ") - assert success == "y" - - print("Interactive test passed.") + passert("interactive success", success == "y") if __name__ == "__main__": @@ -104,11 +97,13 @@ def test_interactive(): i2c_devpath = sys.argv[1] - print("Starting I2C tests...") - test_arguments() + pokay("Arguments test passed.") test_open_close() + pokay("Open/close test passed.") test_loopback() + pokay("Loopback test passed.") test_interactive() + pokay("Interactive test passed.") - print("All I2C tests passed.") + pokay("All tests passed!") diff --git a/tests/test_led.py b/tests/test_led.py index 5913310..e4e4365 100644 --- a/tests/test_led.py +++ b/tests/test_led.py @@ -1,77 +1,80 @@ import os import sys import time + import periphery -from .asserts import AssertRaises +from .test import ptest, pokay, passert, AssertRaises if sys.version_info[0] == 3: raw_input = input + led_name = None def test_arguments(): - print("Starting arguments test...") + ptest() # Invalid open types - with AssertRaises(TypeError): + with AssertRaises("invalid open types", TypeError): periphery.LED("abc", "out") - with AssertRaises(TypeError): + with AssertRaises("invalid open types", TypeError): periphery.LED(100, 100) - print("Arguments test passed.") - def test_open_close(): - print("Starting open/close test...") + ptest() # Open non-existent LED - with AssertRaises(LookupError): + with AssertRaises("non-existent led", LookupError): periphery.LED("invalid_led_XXX", 0) # Open legitimate LED led = periphery.LED(led_name, 0) - assert led.name == led_name - assert led.fd > 0 - assert led.max_brightness > 0 + passert("property name", led.name == led_name) + passert("fd >= 0", led.fd >= 0) + passert("max_brightness > 0", led.max_brightness > 0) # Set brightness to True, check brightness led.write(True) time.sleep(0.01) - assert led.read() == led.max_brightness + passert("brightness is max", led.read() == led.max_brightness) # Set brightness to False, check brightness led.write(False) time.sleep(0.01) - assert led.read() == 0 + passert("brightness is zero", led.read() == 0) # Set brightness to 1, check brightness led.write(1) time.sleep(0.01) - assert led.read() >= 1 + passert("brightness is non-zero", led.read() >= 1) # Set brightness to 0, check brightness led.write(0) time.sleep(0.01) - assert led.read() == 0 + passert("brightness is zero", led.read() == 0) # Set brightness to 1, check brightness led.brightness = 1 time.sleep(0.01) - assert led.brightness >= 1 + passert("brightness is non-zero", led.brightness >= 1) # Set brightness to 0, check brightness led.brightness = 0 time.sleep(0.01) - assert led.brightness == 0 + passert("brightness is zero", led.brightness == 0) led.close() - print("Open/close test passed.") + +def test_loopback(): + ptest() + # No general way to do a loopback test for I2C without a real component, skipping... def test_interactive(): - print("Starting interactive test...") + ptest() led = periphery.LED(led_name, False) @@ -79,28 +82,26 @@ def test_interactive(): # Check tostring print("LED description: {}".format(str(led))) - assert raw_input("LED description looks ok? y/n ") == "y" + passert("interactive success", raw_input("LED description looks ok? y/n ") == "y") # Turn LED off led.write(False) - assert raw_input("LED is off? y/n ") == "y" + passert("interactive success", raw_input("LED is off? y/n ") == "y") # Turn LED on led.write(True) - assert raw_input("LED is on? y/n ") == "y" + passert("interactive success", raw_input("LED is on? y/n ") == "y") # Turn LED off led.write(False) - assert raw_input("LED is off? y/n ") == "y" + passert("interactive success", raw_input("LED is off? y/n ") == "y") # Turn LED on led.write(True) - assert raw_input("LED is on? y/n ") == "y" + passert("interactive success", raw_input("LED is on? y/n ") == "y") led.close() - print("Interactive test passed.") - if __name__ == "__main__": if os.environ.get("CI") == "true": @@ -124,10 +125,13 @@ def test_interactive(): led_name = sys.argv[1] - print("Starting LED tests...") - test_arguments() + pokay("Arguments test passed.") test_open_close() + pokay("Open/close test passed.") + test_loopback() + pokay("Loopback test passed.") test_interactive() + pokay("Interactive test passed.") - print("All LED tests passed.") + pokay("All tests passed!") diff --git a/tests/test_mmio.py b/tests/test_mmio.py index d6fecb4..b3ff954 100644 --- a/tests/test_mmio.py +++ b/tests/test_mmio.py @@ -1,12 +1,14 @@ import os import sys import time + import periphery -from .asserts import AssertRaises +from .test import ptest, pokay, passert, AssertRaises if sys.version_info[0] == 3: raw_input = input + PAGE_SIZE = 4096 CONTROL_MODULE_BASE = 0x44e10000 USB_VID_PID_OFFSET = 0x7f4 @@ -18,59 +20,56 @@ def test_arguments(): - print("Starting arguments test...") - print("Arguments test passed.") + ptest() def test_open_close(): - print("Starting open/close test...") + ptest() # Open aligned base mmio = periphery.MMIO(CONTROL_MODULE_BASE, PAGE_SIZE) # Check properties - assert mmio.base == CONTROL_MODULE_BASE - assert mmio.size == PAGE_SIZE + passert("property base", mmio.base == CONTROL_MODULE_BASE) + passert("property size", mmio.size == PAGE_SIZE) # Try to write immutable properties - with AssertRaises(AttributeError): + with AssertRaises("write immutable", AttributeError): mmio.base = 1000 - with AssertRaises(AttributeError): + with AssertRaises("write immutable", AttributeError): mmio.size = 1000 mmio.close() # Open unaligned base mmio = periphery.MMIO(CONTROL_MODULE_BASE + 123, PAGE_SIZE) # Check properties - assert mmio.base == CONTROL_MODULE_BASE + 123 - assert mmio.size == PAGE_SIZE + passert("property base", mmio.base == CONTROL_MODULE_BASE + 123) + passert("property size", mmio.size == PAGE_SIZE) # Read out of bounds - with AssertRaises(ValueError): + with AssertRaises("read 1 byte over", ValueError): mmio.read32(PAGE_SIZE - 3) - with AssertRaises(ValueError): + with AssertRaises("read 2 bytes over", ValueError): mmio.read32(PAGE_SIZE - 2) - with AssertRaises(ValueError): + with AssertRaises("read 3 bytes over", ValueError): mmio.read32(PAGE_SIZE - 1) - with AssertRaises(ValueError): + with AssertRaises("read 4 bytes over", ValueError): mmio.read32(PAGE_SIZE) mmio.close() - print("Open/close test passed.") - def test_loopback(): - print("Starting loopback test...") + ptest() # Open control module mmio = periphery.MMIO(CONTROL_MODULE_BASE, PAGE_SIZE) # Read and compare USB VID/PID with read32() - assert mmio.read32(USB_VID_PID_OFFSET) == USB_VID_PID + passert("compare USB VID/PID", mmio.read32(USB_VID_PID_OFFSET) == USB_VID_PID) # Read and compare USB VID/PID with bytes read data = mmio.read(USB_VID_PID_OFFSET, 4) data = bytearray(data) - assert data[0] == USB_VID_PID & 0xff - assert data[1] == (USB_VID_PID >> 8) & 0xff - assert data[2] == (USB_VID_PID >> 16) & 0xff - assert data[3] == (USB_VID_PID >> 24) & 0xff + passert("compare byte 1", data[0] == USB_VID_PID & 0xff) + passert("compare byte 2", data[1] == (USB_VID_PID >> 8) & 0xff) + passert("compare byte 3", data[2] == (USB_VID_PID >> 16) & 0xff) + passert("compare byte 4", data[3] == (USB_VID_PID >> 24) & 0xff) mmio.close() @@ -83,44 +82,42 @@ def test_loopback(): # Write/Read RTC Scratch2 Register mmio.write32(RTC_SCRATCH2_REG_OFFSET, 0xdeadbeef) - assert mmio.read32(RTC_SCRATCH2_REG_OFFSET) == 0xdeadbeef + passert("compare write 32-bit uint and readback", mmio.read32(RTC_SCRATCH2_REG_OFFSET) == 0xdeadbeef) # Write/Read RTC Scratch2 Register with bytes write mmio.write(RTC_SCRATCH2_REG_OFFSET, b"\xaa\xbb\xcc\xdd") data = mmio.read(RTC_SCRATCH2_REG_OFFSET, 4) - assert data == b"\xaa\xbb\xcc\xdd" + passert("compare write 4-byte bytes and readback", data == b"\xaa\xbb\xcc\xdd") # Write/Read RTC Scratch2 Register with bytearray write mmio.write(RTC_SCRATCH2_REG_OFFSET, bytearray(b"\xbb\xcc\xdd\xee")) data = mmio.read(RTC_SCRATCH2_REG_OFFSET, 4) - assert data == b"\xbb\xcc\xdd\xee" + passert("compare write 4-byte bytearray and readback", data == b"\xbb\xcc\xdd\xee") # Write/Read RTC Scratch2 Register with list write mmio.write(RTC_SCRATCH2_REG_OFFSET, [0xcc, 0xdd, 0xee, 0xff]) data = mmio.read(RTC_SCRATCH2_REG_OFFSET, 4) - assert data == b"\xcc\xdd\xee\xff" + passert("compare write 4-byte list and readback", data == b"\xcc\xdd\xee\xff") # Write/Read RTC Scratch2 Register with 16-bit write mmio.write16(RTC_SCRATCH2_REG_OFFSET, 0xaabb) - assert mmio.read16(RTC_SCRATCH2_REG_OFFSET) == 0xaabb + passert("compare write 16-bit uint and readback", mmio.read16(RTC_SCRATCH2_REG_OFFSET) == 0xaabb) # Write/Read RTC Scratch2 Register with 8-bit write - mmio.write16(RTC_SCRATCH2_REG_OFFSET, 0xab) - assert mmio.read8(RTC_SCRATCH2_REG_OFFSET) == 0xab + mmio.write8(RTC_SCRATCH2_REG_OFFSET, 0xab) + passert("compare write 8-bit uint and readback", mmio.read8(RTC_SCRATCH2_REG_OFFSET) == 0xab) mmio.close() - print("Loopback test passed.") - def test_interactive(): - print("Starting interactive test...") + ptest() mmio = periphery.MMIO(RTCSS_BASE, PAGE_SIZE) # Check tostring print("MMIO description: {}".format(str(mmio))) - assert raw_input("MMIO description looks ok? y/n ") == "y" + passert("interactive success", raw_input("MMIO description looks ok? y/n ") == "y") print("Waiting for seconds ones digit to reset to 0...\n") @@ -129,7 +126,7 @@ def test_interactive(): tic = time.time() while mmio.read32(0x00) & 0xf != 0: periphery.sleep(1) - assert (time.time() - tic) < 12 + passert("less than 12 seconds elapsed", (time.time() - tic) < 12) # Compare passage of OS time with RTC time @@ -149,13 +146,11 @@ def test_interactive(): toc = time.time() rtc_toc = mmio.read32(0x00) & 0xf - assert (toc - tic) > 2 - assert (rtc_toc - rtc_tic) > 2 + passert("real time elapsed", (toc - tic) > 2) + passert("rtc time elapsed", (rtc_toc - rtc_tic) > 2) mmio.close() - print("Interactive test passed.") - if __name__ == "__main__": if os.environ.get("CI") == "true": @@ -166,11 +161,13 @@ def test_interactive(): print("Other systems may experience unintended and dire consequences!") raw_input("Press enter to continue!") - print("Starting MMIO tests...") - test_arguments() + pokay("Arguments test passed.") test_open_close() + pokay("Open/close test passed.") test_loopback() + pokay("Loopback test passed.") test_interactive() + pokay("Interactive test passed.") - print("All MMIO tests passed.") + pokay("All tests passed!") diff --git a/tests/test_pwm.py b/tests/test_pwm.py index 848cfec..391ae49 100644 --- a/tests/test_pwm.py +++ b/tests/test_pwm.py @@ -1,42 +1,43 @@ import os import sys + import periphery -from .asserts import AssertRaises +from .test import ptest, pokay, passert, AssertRaises if sys.version_info[0] == 3: raw_input = input + pwm_chip = None pwm_channel = None def test_arguments(): - print("Starting arguments test...") + ptest() # Invalid open types - with AssertRaises(TypeError): + with AssertRaises("invalid open types", TypeError): periphery.PWM("foo", 0) - with AssertRaises(TypeError): + with AssertRaises("invalid open types", TypeError): periphery.PWM(0, "foo") - print("Arguments test passed.") def test_open_close(): - print("Starting open/close test...") + ptest() # Open non-existent PWM chip - with AssertRaises(LookupError): + with AssertRaises("non-existent PWM chip", LookupError): periphery.PWM(9999, pwm_channel) # Open non-existent PWM channel - with AssertRaises(periphery.PWMError): + with AssertRaises("non-existent PWM channel", periphery.PWMError): periphery.PWM(pwm_chip, 9999) # Open legitimate PWM chip/channel pwm = periphery.PWM(pwm_chip, pwm_channel) - assert pwm.chip == pwm_chip - assert pwm.channel == pwm_channel + passert("property chip", pwm.chip == pwm_chip) + passert("property channel", pwm.channel == pwm_channel) # Initialize period and duty cycle pwm.period = 5e-3 @@ -44,85 +45,87 @@ def test_open_close(): # Set period, check period, check period_ns, check frequency pwm.period = 1e-3 - assert abs(pwm.period - 1e-3) < 1e-4 - assert abs(pwm.period_ns - 1000000) < 1e5 - assert abs(pwm.frequency - 1000) < 100 + passert("period is correct", abs(pwm.period - 1e-3) < 1e-4) + passert("period_ns is correct", abs(pwm.period_ns - 1000000) < 1e5) + passert("frequency is correct", abs(pwm.frequency - 1000) < 100) pwm.period = 5e-4 - assert abs(pwm.period - 5e-4) < 1e-5 - assert abs(pwm.period_ns - 500000) < 1e4 - assert abs(pwm.frequency - 2000) < 100 + passert("period is correct", abs(pwm.period - 5e-4) < 1e-5) + passert("period_ns is correct", abs(pwm.period_ns - 500000) < 1e4) + passert("frequency is correct", abs(pwm.frequency - 2000) < 100) # Set frequency, check frequency, check period, check period_ns pwm.frequency = 1000 - assert abs(pwm.frequency - 1000) < 100 - assert abs(pwm.period - 1e-3) < 1e-4 - assert abs(pwm.period_ns - 1000000) < 1e5 + passert("frequency is correct", abs(pwm.frequency - 1000) < 100) + passert("period is correct", abs(pwm.period - 1e-3) < 1e-4) + passert("period_ns is correct", abs(pwm.period_ns - 1000000) < 1e5) pwm.frequency = 2000 - assert abs(pwm.frequency - 2000) < 100 - assert abs(pwm.period - 5e-4) < 1e-5 - assert abs(pwm.period_ns - 500000) < 1e4 + passert("frequency is correct", abs(pwm.frequency - 2000) < 100) + passert("period is correct", abs(pwm.period - 5e-4) < 1e-5) + passert("period_ns is correct", abs(pwm.period_ns - 500000) < 1e4) # Set period_ns, check period_ns, check period, check frequency pwm.period_ns = 1000000 - assert abs(pwm.period_ns - 1000000) < 1e5 - assert abs(pwm.period - 1e-3) < 1e-4 - assert abs(pwm.frequency - 1000) < 100 + passert("period_ns is correct", abs(pwm.period_ns - 1000000) < 1e5) + passert("period is correct", abs(pwm.period - 1e-3) < 1e-4) + passert("frequency is correct", abs(pwm.frequency - 1000) < 100) pwm.period_ns = 500000 - assert abs(pwm.period_ns - 500000) < 1e4 - assert abs(pwm.period - 5e-4) < 1e-5 - assert abs(pwm.frequency - 2000) < 100 + passert("period_ns is correct", abs(pwm.period_ns - 500000) < 1e4) + passert("period is correct", abs(pwm.period - 5e-4) < 1e-5) + passert("frequency is correct", abs(pwm.frequency - 2000) < 100) pwm.period_ns = 1000000 # Set duty cycle, check duty cycle, check duty_cycle_ns pwm.duty_cycle = 0.25 - assert abs(pwm.duty_cycle - 0.25) < 1e-3 - assert abs(pwm.duty_cycle_ns - 250000) < 1e4 + passert("duty_cycle is correct", abs(pwm.duty_cycle - 0.25) < 1e-3) + passert("duty_cycle_ns is correct", abs(pwm.duty_cycle_ns - 250000) < 1e4) pwm.duty_cycle = 0.50 - assert abs(pwm.duty_cycle - 0.50) < 1e-3 - assert abs(pwm.duty_cycle_ns - 500000) < 1e4 + passert("duty_cycle is correct", abs(pwm.duty_cycle - 0.50) < 1e-3) + passert("duty_cycle_ns is correct", abs(pwm.duty_cycle_ns - 500000) < 1e4) pwm.duty_cycle = 0.75 - assert abs(pwm.duty_cycle - 0.75) < 1e-3 - assert abs(pwm.duty_cycle_ns - 750000) < 1e4 + passert("duty_cycle is correct", abs(pwm.duty_cycle - 0.75) < 1e-3) + passert("duty_cycle_ns is correct", abs(pwm.duty_cycle_ns - 750000) < 1e4) # Set duty_cycle_ns, check duty_cycle_ns, check duty_cycle pwm.duty_cycle_ns = 250000 - assert abs(pwm.duty_cycle_ns - 250000) < 1e4 - assert abs(pwm.duty_cycle - 0.25) < 1e-3 + passert("duty_cycle_ns is correct", abs(pwm.duty_cycle_ns - 250000) < 1e4) + passert("duty_cycle is correct", abs(pwm.duty_cycle - 0.25) < 1e-3) pwm.duty_cycle_ns = 500000 - assert abs(pwm.duty_cycle_ns - 500000) < 1e4 - assert abs(pwm.duty_cycle - 0.50) < 1e-3 + passert("duty_cycle_ns is correct", abs(pwm.duty_cycle_ns - 500000) < 1e4) + passert("duty_cycle is correct", abs(pwm.duty_cycle - 0.50) < 1e-3) pwm.duty_cycle_ns = 750000 - assert abs(pwm.duty_cycle_ns - 750000) < 1e4 - assert abs(pwm.duty_cycle - 0.75) < 1e-3 + passert("duty_cycle_ns is correct", abs(pwm.duty_cycle_ns - 750000) < 1e4) + passert("duty_cycle is correct", abs(pwm.duty_cycle - 0.75) < 1e-3) # Set polarity, check polarity pwm.polarity = "normal" - assert pwm.polarity == "normal" + passert("polarity is normal", pwm.polarity == "normal") pwm.polarity = "inversed" - assert pwm.polarity == "inversed" + passert("polarity is inversed", pwm.polarity == "inversed") # Set enabled, check enabled pwm.enabled = True - assert pwm.enabled == True + passert("pwm is enabled", pwm.enabled == True) pwm.enabled = False - assert pwm.enabled == False + passert("pwm is disabled", pwm.enabled == False) # Use enable()/disable(), check enabled pwm.enable() - assert pwm.enabled == True + passert("pwm is enabled", pwm.enabled == True) pwm.disable() - assert pwm.enabled == False + passert("pwm is disabled", pwm.enabled == False) # Set invalid polarity - with AssertRaises(ValueError): + with AssertRaises("set invalid polarity", ValueError): pwm.polarity = "foo" pwm.close() - print("Open/close test passed.") + +def test_loopback(): + ptest() def test_interactive(): - print("Starting interactive test...") + ptest() pwm = periphery.PWM(pwm_chip, pwm_channel) @@ -137,35 +140,33 @@ def test_interactive(): # Check tostring print("PWM description: {}".format(str(pwm))) - assert raw_input("PWM description looks ok? y/n ") == "y" + passert("interactive success", raw_input("PWM description looks ok? y/n ") == "y") # Set 1 kHz frequency, 0.25 duty cycle pwm.frequency = 1e3 pwm.duty_cycle = 0.25 - assert raw_input("Frequency is 1 kHz, duty cycle is 25%? y/n ") == "y" + passert("interactive success", raw_input("Frequency is 1 kHz, duty cycle is 25%? y/n ") == "y") # Set 1 kHz frequency, 0.50 duty cycle pwm.frequency = 1e3 pwm.duty_cycle = 0.50 - assert raw_input("Frequency is 1 kHz, duty cycle is 50%? y/n ") == "y" + passert("interactive success", raw_input("Frequency is 1 kHz, duty cycle is 50%? y/n ") == "y") # Set 2 kHz frequency, 0.25 duty cycle pwm.frequency = 2e3 pwm.duty_cycle = 0.25 - assert raw_input("Frequency is 2 kHz, duty cycle is 25%? y/n ") == "y" + passert("interactive success", raw_input("Frequency is 2 kHz, duty cycle is 25%? y/n ") == "y") # Set 2 kHz frequency, 0.50 duty cycle pwm.frequency = 2e3 pwm.duty_cycle = 0.50 - assert raw_input("Frequency is 2 kHz, duty cycle is 50%? y/n ") == "y" + passert("interactive success", raw_input("Frequency is 2 kHz, duty cycle is 50%? y/n ") == "y") pwm.duty_cycle = 0.0 pwm.enabled = False pwm.close() - print("Interactive test passed.") - if __name__ == "__main__": if os.environ.get("CI") == "true": @@ -194,10 +195,13 @@ def test_interactive(): pwm_chip = int(sys.argv[1]) pwm_channel = int(sys.argv[2]) - print("Starting PMW tests...") - test_arguments() + pokay("Arguments test passed.") test_open_close() + pokay("Open/close test passed.") + test_loopback() + pokay("Loopback test passed.") test_interactive() + pokay("Interactive test passed.") - print("All PWM tests passed.") + pokay("All tests passed!") diff --git a/tests/test_serial.py b/tests/test_serial.py index 5efc1c6..38771b4 100644 --- a/tests/test_serial.py +++ b/tests/test_serial.py @@ -1,79 +1,77 @@ import os import sys import time + import periphery -from .asserts import AssertRaises +from .test import ptest, pokay, passert, AssertRaises if sys.version_info[0] == 3: raw_input = input + serial_device = None def test_arguments(): - print("Starting arguments test...") + ptest() # Invalid data bits - with AssertRaises(ValueError): + with AssertRaises("invalid databits", ValueError): periphery.Serial("/dev/ttyS0", 115200, databits=4) - with AssertRaises(ValueError): + with AssertRaises("invalid databits", ValueError): periphery.Serial("/dev/ttyS0", 115200, databits=9) # Invalid parity - with AssertRaises(ValueError): + with AssertRaises("invalid parity", ValueError): periphery.Serial("/dev/ttyS0", 115200, parity="blah") # Invalid stop bits - with AssertRaises(ValueError): + with AssertRaises("invalid stop bits", ValueError): periphery.Serial("/dev/ttyS0", 115200, stopbits=0) - with AssertRaises(ValueError): + with AssertRaises("invalid stop bits", ValueError): periphery.Serial("/dev/ttyS0", 115200, stopbits=3) # Everything else is fair game, although termios might not like it. - print("Arguments test passed.") - def test_open_close(): - print("Starting open/close test...") + ptest() serial = periphery.Serial(serial_device, 115200) # Confirm default settings - assert serial.fd > 0 - assert serial.baudrate == 115200 - assert serial.databits == 8 - assert serial.parity == "none" - assert serial.stopbits == 1 - assert serial.xonxoff == False - assert serial.rtscts == False - assert serial.vmin == 0 - assert serial.vtime == 0 + passert("fd > 0", serial.fd > 0) + passert("baudrate is 115200", serial.baudrate == 115200) + passert("databits is 8", serial.databits == 8) + passert("parity is none", serial.parity == "none") + passert("stopbits is 1", serial.stopbits == 1) + passert("xonxoff is False", serial.xonxoff == False) + passert("rtscts is False", serial.rtscts == False) + passert("vmin is 0", serial.vmin == 0) + passert("vtime is 0", serial.vtime == 0) # Change some stuff and check that it changed serial.baudrate = 4800 - assert serial.baudrate == 4800 + passert("baudrate is 4800", serial.baudrate == 4800) serial.baudrate = 9600 - assert serial.baudrate == 9600 + passert("baudrate is 9600", serial.baudrate == 9600) serial.databits = 7 - assert serial.databits == 7 + passert("databits is 7", serial.databits == 7) serial.parity = "odd" - assert serial.parity == "odd" + passert("parity is odd", serial.parity == "odd") serial.stopbits = 2 - assert serial.stopbits == 2 + passert("stopbits is 2", serial.stopbits == 2) serial.xonxoff = True - assert serial.xonxoff == True + passert("xonxoff is True", serial.xonxoff == True) # Test serial port may not support rtscts serial.vmin = 50 - assert serial.vmin == 50 + passert("vmin is 50", serial.vmin == 50) serial.vtime = 15.3 - assert abs(serial.vtime - 15.3) < 0.1 + passert("vtime is 15.3", abs(serial.vtime - 15.3) < 0.1) serial.close() - print("Open/close test passed.") - def test_loopback(): - print("Starting loopback test...") + ptest() lorem_ipsum = b"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." @@ -81,89 +79,87 @@ def test_loopback(): # Test write/flush/read with bytes write print("Write, flush, read lorem ipsum with bytes type") - assert serial.write(lorem_ipsum) == len(lorem_ipsum) + passert("wrote lorem ipsum bytes", serial.write(lorem_ipsum) == len(lorem_ipsum)) serial.flush() buf = serial.read(len(lorem_ipsum), timeout=3) - assert buf == lorem_ipsum + passert("compare readback lorem ipsum", buf == lorem_ipsum) # Test write/flush/read with bytearray write print("Write, flush, read lorem ipsum with bytearray type") - assert serial.write(bytearray(lorem_ipsum)) == len(lorem_ipsum) + passert("wrote lorem ipsum bytearray", serial.write(bytearray(lorem_ipsum)) == len(lorem_ipsum)) serial.flush() buf = serial.read(len(lorem_ipsum), timeout=3) - assert buf == lorem_ipsum + passert("compare readback lorem ipsum", buf == lorem_ipsum) # Test write/flush/read with list write print("Write, flush, read lorem ipsum with list type") - assert serial.write(list(bytearray(lorem_ipsum))) == len(lorem_ipsum) + passert("write lorem ipsum list", serial.write(list(bytearray(lorem_ipsum))) == len(lorem_ipsum)) serial.flush() buf = serial.read(len(lorem_ipsum), timeout=3) - assert buf == lorem_ipsum + passert("compare readback lorem ipsum", buf == lorem_ipsum) # Test poll/write/flush/poll/input waiting/read print("Write, flush, poll, input waiting, read lorem ipsum") - assert serial.poll(0.5) == False - assert serial.write(lorem_ipsum) == len(lorem_ipsum) + passert("poll timed out", serial.poll(0.5) == False) + passert("write lorem ipsum", serial.write(lorem_ipsum) == len(lorem_ipsum)) serial.flush() - assert serial.poll(0.5) == True + passert("poll succeeded", serial.poll(0.5) == True) periphery.sleep_ms(500) - assert serial.input_waiting() == len(lorem_ipsum) + passert("input waiting is lorem ipsum size", serial.input_waiting() == len(lorem_ipsum)) buf = serial.read(len(lorem_ipsum)) - assert buf == lorem_ipsum + passert("compare readback lorem ipsum", buf == lorem_ipsum) # Test non-blocking poll print("Check non-blocking poll") - assert serial.poll(0) == False + passert("non-blocking poll is False", serial.poll(0) == False) # Test a very large read-write (likely to exceed internal buffer size (~4096)) print("Write, flush, read large buffer") lorem_hugesum = b"\xaa" * (4096 * 3) - assert serial.write(lorem_hugesum) == len(lorem_hugesum) + passert("wrote lorem hugesum", serial.write(lorem_hugesum) == len(lorem_hugesum)) serial.flush() buf = serial.read(len(lorem_hugesum), timeout=3) - assert buf == lorem_hugesum + passert("compare readback lorem hugesum", buf == lorem_hugesum) # Test read timeout print("Check read timeout") tic = time.time() - assert serial.read(4096 * 3, timeout=2) == b"" + passert("read timed out", serial.read(4096 * 3, timeout=2) == b"") toc = time.time() - assert (toc - tic) > 1 + passert("time elapsed", (toc - tic) > 1) # Test non-blocking read print("Check non-blocking read") tic = time.time() - assert serial.read(4096 * 3, timeout=0) == b"" + passert("read non-blocking is empty", serial.read(4096 * 3, timeout=0) == b"") toc = time.time() # Assuming we weren't context switched out for a second - assert int(toc - tic) == 0 + passert("almost no time elapsed", int(toc - tic) == 0) # Test blocking read with vmin=5 termios timeout print("Check blocking read with vmin termios timeout") serial.vmin = 5 - assert serial.write(lorem_ipsum[0:5]) == 5 + passert("write 5 bytes of lorem ipsum", serial.write(lorem_ipsum[0:5]) == 5) serial.flush() buf = serial.read(len(lorem_ipsum)) - assert buf == lorem_ipsum[0:5] + passert("compare readback partial lorem ipsum", buf == lorem_ipsum[0:5]) # Test blocking read with vmin=5, vtime=2 termios timeout print("Check blocking read with vmin + vtime termios timeout") serial.vtime = 2 - assert serial.write(lorem_ipsum[0:3]) == 3 + passert("write 3 bytes of lorem ipsum", serial.write(lorem_ipsum[0:3]) == 3) serial.flush() tic = time.time() buf = serial.read(len(lorem_ipsum)) toc = time.time() - assert buf == lorem_ipsum[0:3] - assert (toc - tic) > 1 + passert("compare readback partial lorem ipsum", buf == lorem_ipsum[0:3]) + passert("time elapsed", (toc - tic) > 1) serial.close() - print("Loopback test passed.") - def test_interactive(): - print("Starting interactive test...") + ptest() buf = b"Hello World!" @@ -174,27 +170,25 @@ def test_interactive(): # Check tostring print("Serial description: {}".format(str(serial))) - assert raw_input("Serial description looks ok? y/n ") == "y" + passert("interactive success", raw_input("Serial description looks ok? y/n ") == "y") serial.baudrate = 4800 raw_input("Press enter to start transfer...") - assert serial.write(buf) == len(buf) - assert raw_input("Serial transfer baudrate 4800, 8n1 occurred? y/n ") == "y" + passert("serial write", serial.write(buf) == len(buf)) + passert("interactive success", raw_input("Serial transfer baudrate 4800, 8n1 occurred? y/n ") == "y") serial.baudrate = 9600 raw_input("Press enter to start transfer...") - assert serial.write(buf) == len(buf) - assert raw_input("Serial transfer baudrate 9600, 8n1 occurred? y/n ") == "y" + passert("serial write", serial.write(buf) == len(buf)) + passert("interactive success", raw_input("Serial transfer baudrate 9600, 8n1 occurred? y/n ") == "y") serial.baudrate = 115200 raw_input("Press enter to start transfer...") - assert serial.write(buf) == len(buf) - assert raw_input("Serial transfer baudrate 115200, 8n1 occurred? y/n ") == "y" + passert("serial write", serial.write(buf) == len(buf)) + passert("interactive success", raw_input("Serial transfer baudrate 115200, 8n1 occurred? y/n ") == "y") serial.close() - print("Interactive test passed.") - if __name__ == "__main__": if os.environ.get("CI") == "true": @@ -222,11 +216,13 @@ def test_interactive(): serial_device = sys.argv[1] - print("Starting Serial tests...") - test_arguments() + pokay("Arguments test passed.") test_open_close() + pokay("Open/close test passed.") test_loopback() + pokay("Loopback test passed.") test_interactive() + pokay("Interactive test passed.") - print("All Serial tests passed.") + pokay("All tests passed!") diff --git a/tests/test_spi.py b/tests/test_spi.py index 7487ce7..45a1bdc 100644 --- a/tests/test_spi.py +++ b/tests/test_spi.py @@ -1,96 +1,92 @@ import os import sys + import periphery -from .asserts import AssertRaises +from .test import ptest, pokay, passert, AssertRaises if sys.version_info[0] == 3: raw_input = input + spi_device = None def test_arguments(): - print("Starting arguments test...") + ptest() # Invalid mode - with AssertRaises(ValueError): + with AssertRaises("invalid mode", ValueError): periphery.SPI("/dev/spidev0.0", 4, int(1e6)) # Invalid bit order - with AssertRaises(ValueError): + with AssertRaises("invalid bit order", ValueError): periphery.SPI("/dev/spidev0.0", 4, int(1e6), bit_order="blah") - print("Arguments test passed.") - def test_open_close(): - print("Starting open/close test...") + ptest() # Normal open (mode=1, max_speed = 100000) spi = periphery.SPI(spi_device, 1, 100000) # Confirm fd and defaults - assert spi.fd > 0 - assert spi.mode == 1 - assert spi.max_speed == 100000 - assert spi.bit_order == "msb" - assert spi.bits_per_word == 8 - assert spi.extra_flags == 0 + passert("fd > 0", spi.fd > 0) + passert("mode is 1", spi.mode == 1) + passert("max speed is 100000", spi.max_speed == 100000) + passert("default bit_order is msb", spi.bit_order == "msb") + passert("default bits_per_word is 8", spi.bits_per_word == 8) + passert("default extra_flags is 0", spi.extra_flags == 0) # Not going to try different bit order or bits per word, because not # all SPI controllers support them # Try modes 0, 1, 2, 3 spi.mode = 0 - assert spi.mode == 0 + passert("spi mode is 0", spi.mode == 0) spi.mode = 1 - assert spi.mode == 1 + passert("spi mode is 1", spi.mode == 1) spi.mode = 2 - assert spi.mode == 2 + passert("spi mode is 2", spi.mode == 2) spi.mode = 3 - assert spi.mode == 3 + passert("spi mode is 3", spi.mode == 3) # Try max speeds 100Khz, 500KHz, 1MHz, 2MHz spi.max_speed = 100000 - assert spi.max_speed == 100000 + passert("max speed is 100KHz", spi.max_speed == 100000) spi.max_speed = 500000 - assert spi.max_speed == 500000 + passert("max speed is 500KHz", spi.max_speed == 500000) spi.max_speed = 1000000 - assert spi.max_speed == 1000000 + passert("max speed is 1MHz", spi.max_speed == 1000000) spi.max_speed = 2e6 - assert spi.max_speed == 2000000 + passert("max speed is 2MHz", spi.max_speed == 2000000) spi.close() - print("Open/close test passed.") - def test_loopback(): - print("Starting loopback test...") + ptest() spi = periphery.SPI(spi_device, 0, 100000) # Try list transfer buf_in = list(range(256)) * 4 buf_out = spi.transfer(buf_in) - assert buf_out == buf_in + passert("compare readback", buf_out == buf_in) # Try bytearray transfer buf_in = bytearray(buf_in) buf_out = spi.transfer(buf_in) - assert buf_out == buf_in + passert("compare readback", buf_out == buf_in) # Try bytes transfer buf_in = bytes(bytearray(buf_in)) buf_out = spi.transfer(buf_in) - assert buf_out == buf_in + passert("compare readback", buf_out == buf_in) spi.close() - print("Loopback test passed.") - def test_interactive(): - print("Starting interactive test...") + ptest() spi = periphery.SPI(spi_device, 0, 100000) @@ -99,34 +95,34 @@ def test_interactive(): # Check tostring print("SPI description: {}".format(str(spi))) - assert raw_input("SPI description looks ok? y/n ") == "y" + passert("interactive success", raw_input("SPI description looks ok? y/n ") == "y") # Mode 0 transfer raw_input("Press enter to start transfer...") spi.transfer([0x55, 0xaa, 0x0f, 0xf0]) print("SPI data 0x55, 0xaa, 0x0f, 0xf0") - assert raw_input("SPI transfer speed <= 100KHz, mode 0 occurred? y/n ") == "y" + passert("interactive success", raw_input("SPI transfer speed <= 100KHz, mode 0 occurred? y/n ") == "y") # Mode 1 transfer spi.mode = 1 raw_input("Press enter to start transfer...") spi.transfer([0x55, 0xaa, 0x0f, 0xf0]) print("SPI data 0x55, 0xaa, 0x0f, 0xf0") - assert raw_input("SPI transfer speed <= 100KHz, mode 1 occurred? y/n ") == "y" + passert("interactive success", raw_input("SPI transfer speed <= 100KHz, mode 1 occurred? y/n ") == "y") # Mode 2 transfer spi.mode = 2 raw_input("Press enter to start transfer...") spi.transfer([0x55, 0xaa, 0x0f, 0xf0]) print("SPI data 0x55, 0xaa, 0x0f, 0xf0") - assert raw_input("SPI transfer speed <= 100KHz, mode 2 occurred? y/n ") == "y" + passert("interactive success", raw_input("SPI transfer speed <= 100KHz, mode 2 occurred? y/n ") == "y") # Mode 3 transfer spi.mode = 3 raw_input("Press enter to start transfer...") spi.transfer([0x55, 0xaa, 0x0f, 0xf0]) print("SPI data 0x55, 0xaa, 0x0f, 0xf0") - assert raw_input("SPI transfer speed <= 100KHz, mode 3 occurred? y/n ") == "y" + passert("interactive success", raw_input("SPI transfer speed <= 100KHz, mode 3 occurred? y/n ") == "y") spi.mode = 0 @@ -135,19 +131,17 @@ def test_interactive(): raw_input("Press enter to start transfer...") spi.transfer([0x55, 0xaa, 0x0f, 0xf0]) print("SPI data 0x55, 0xaa, 0x0f, 0xf0") - assert raw_input("SPI transfer speed <= 500KHz, mode 0 occurred? y/n ") == "y" + passert("interactive success", raw_input("SPI transfer speed <= 500KHz, mode 0 occurred? y/n ") == "y") # 1MHz transfer spi.max_speed = 1000000 raw_input("Press enter to start transfer...") spi.transfer([0x55, 0xaa, 0x0f, 0xf0]) print("SPI data 0x55, 0xaa, 0x0f, 0xf0") - assert raw_input("SPI transfer speed <= 1MHz, mode 0 occurred? y/n ") == "y" + passert("interactive success", raw_input("SPI transfer speed <= 1MHz, mode 0 occurred? y/n ") == "y") spi.close() - print("Interactive test passed.") - if __name__ == "__main__": if os.environ.get("CI") == "true": @@ -173,11 +167,13 @@ def test_interactive(): spi_device = sys.argv[1] - print("Starting SPI tests...") - test_arguments() + pokay("Arguments test passed.") test_open_close() + pokay("Open/close test passed.") test_loopback() + pokay("Loopback test passed.") test_interactive() + pokay("Interactive test passed.") - print("All SPI tests passed.") + pokay("All tests passed!")