From 9a41ca0fda8aab14484d48239e0d73b4f8cca7fb Mon Sep 17 00:00:00 2001 From: Jeroen Doggen Date: Fri, 4 Jan 2013 01:58:14 +0100 Subject: [PATCH] almost 'pylint clean" --- arduino_testsuite/__init__.py | 2 +- arduino_testsuite/__main__.py | 2 +- arduino_testsuite/infoprinter.py | 6 +- arduino_testsuite/main.py | 8 +- arduino_testsuite/settings.py | 56 ++++++------- arduino_testsuite/test.py | 20 +++-- arduino_testsuite/testhelper.py | 46 +++++----- arduino_testsuite/tests/test.py | 17 +--- arduino_testsuite/testsuite.py | 140 +++++++++++++------------------ 9 files changed, 131 insertions(+), 166 deletions(-) diff --git a/arduino_testsuite/__init__.py b/arduino_testsuite/__init__.py index cb5e9dd..67c5c15 100644 --- a/arduino_testsuite/__init__.py +++ b/arduino_testsuite/__init__.py @@ -1,4 +1,4 @@ -""" Initialize the package +""" arduino_testsuite: Initialize the package This file is needed to import the module properly The version number is used to generate the PyPI package diff --git a/arduino_testsuite/__main__.py b/arduino_testsuite/__main__.py index d172cac..655f751 100644 --- a/arduino_testsuite/__main__.py +++ b/arduino_testsuite/__main__.py @@ -1,4 +1,4 @@ -""" Main file to run +""" arduino_testsuite: Main file to run This file is needed to be able to run a Python program in a folder directly by calling "Python foldername" diff --git a/arduino_testsuite/infoprinter.py b/arduino_testsuite/infoprinter.py index bee1d62..57eb750 100644 --- a/arduino_testsuite/infoprinter.py +++ b/arduino_testsuite/infoprinter.py @@ -45,11 +45,13 @@ def planned_tests(test_list): programflow() -def setup_info(item): +def setup_info(index, current_test): """Print text at start of a test.""" print ("") double_line() - print ("Starting test: " + item) + print ("Starting test ", end="") + print (index + 1, end=": ") + print (current_test) single_line() print ("Compiling & uploading sketch to Arduino...") diff --git a/arduino_testsuite/main.py b/arduino_testsuite/main.py index d3726b5..70e3997 100644 --- a/arduino_testsuite/main.py +++ b/arduino_testsuite/main.py @@ -29,10 +29,10 @@ def run(): """Run the main program""" suite = TestSuite() timeout = 10 - suite.printPlannedTests() - suite.runTests(timeout) - suite.printSummary() - return(suite.exitValue()) + suite.print_planned_tests() + suite.run_tests(timeout) + suite.print_summary() + return(suite.exit_value()) if __name__ == "__main__": diff --git a/arduino_testsuite/settings.py b/arduino_testsuite/settings.py index a161021..29b31db 100644 --- a/arduino_testsuite/settings.py +++ b/arduino_testsuite/settings.py @@ -1,23 +1,10 @@ -#!/usr/bin/env python -# -# Arduino TestSuite to automate unit tests on the Arduino platform -# Copyright (C) 2012 Jeroen Doggen -# More info in "main.py" -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. +""" arduino_testsuite: Settings class -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +get the cli arguments +setup the serial port +read the config file -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -# MA 02110-1301, USA. +""" from __future__ import print_function, division # We require Python 2.6+ @@ -30,18 +17,23 @@ logging.basicConfig(filename='example.log', level=logging.DEBUG, format='%(asctime)s %(name)s %(message)s') -logger = logging.getLogger(__name__) +LOGGER = logging.getLogger(__name__) class Settings: + """Configure the settings of the program""" DEFAULT_PORT = "/dev/ttyUSB0" DEFAULT_BAUDRATE = 9600 DEFAULT_CONFIGFILE = "planned-tests.conf" - serialPort = DEFAULT_PORT + serial_port = DEFAULT_PORT baudrate = DEFAULT_BAUDRATE - configFile = DEFAULT_CONFIGFILE + config_file = DEFAULT_CONFIGFILE - def getCliArguments(self): + def __init__(self): + """Initialize the settings: do nothing for now.""" + pass + + def get_cli_arguments(self): """Read all the cli arguments.""" """This needs to be indented like this to print it correctly on cli""" parser = argparse.ArgumentParser( @@ -59,32 +51,32 @@ def getCliArguments(self): help='Set the baudrate of the serial port') args = parser.parse_args() if (args.p is not None): - self.serialPort = args.p + self.serial_port = args.p if (args.f is not None): - self.configFile = args.f + self.config_file = args.f if (args.b is not None): self.baudrate = args.b - def initSerialPort(self): + def init_serial_port(self): """Initialize the serial port.""" try: - ser = serial.Serial(self.serialPort, self.baudrate) + ser = serial.Serial(self.serial_port, self.baudrate) ser.flush() except IOError: logger.warning("Unable to connect to serial port") print("Unable to connect to serial port: ", end="") - print(self.serialPort) + print(self.serial_port) sys.exit(1) return(ser) - def readConfigfile(self): + def read_testlist_file(self): """Read the config file to get the testlist.""" - testList = [] + test_list = [] try: - with open(self.configFile, 'r') as f: - testList = f.read().splitlines() + with open(self.config_file, 'r') as configfile: + test_list = configfile.read().splitlines() except IOError: print ("Error: 'planned-tests.conf' not found!") print ("Aborting test session.") sys.exit(1) - return testList + return test_list diff --git a/arduino_testsuite/test.py b/arduino_testsuite/test.py index 57ba4ac..bc79e7a 100644 --- a/arduino_testsuite/test.py +++ b/arduino_testsuite/test.py @@ -1,19 +1,25 @@ +""" arduino_testsuite: Unit tests +nothing useful in here at the moment + +""" import unittest -import random -from arduino_testsuite.testhelper import TestHelper -helper = TestHelper() +class ArduinoTestSuite(unittest.TestCase): + """Test the Arduino + this part of the code could/should be called by 'nose' in the future -class testArduino(unittest.TestCase): + """ - def setUp(self): - self.seq = range(10) + def setup(self): + """Do the test setup""" + pass - def test_runArduinoTests(self): + def test_run_arduino_tests(self): + """Run the tests on the hardware""" self.assertEqual(0, 0) diff --git a/arduino_testsuite/testhelper.py b/arduino_testsuite/testhelper.py index 2831162..1b7e0f4 100644 --- a/arduino_testsuite/testhelper.py +++ b/arduino_testsuite/testhelper.py @@ -1,3 +1,10 @@ +""" arduino_testsuite: Test helper functions + +run a command with a given timeout +return the exit value for the program + +""" + from __future__ import print_function, division # We require Python 2.6+ import time @@ -7,28 +14,19 @@ import signal -class TestHelper: - def timeout_command(self, command, timeout): - #"""call shell-command and either return its output or kill it - #if it doesn't normally exit within timeout seconds and return None""" - - cmd = command.split(" ") - start = datetime.datetime.now() - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - - while process.poll() is None: - now = datetime.datetime.now() - time.sleep(1) - if (now - start).seconds > timeout: - print ("Process timeout") - os.kill(process.pid, signal.SIGKILL) - os.waitpid(-1, os.WNOHANG) - return None - return process.poll() +def timed_cmd(command, timeout): + """Call a cmd and kill it after 'timeout' seconds""" + cmd = command.split(" ") + start = datetime.datetime.now() + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) - def exitValue(self, failureCount): - if (failureCount == 0): - return 0 - else: - return 42 + while process.poll() is None: + now = datetime.datetime.now() + time.sleep(1) + if (now - start).seconds > timeout: + print ("Process timeout") + os.kill(process.pid, signal.SIGKILL) + os.waitpid(-1, os.WNOHANG) + return None + return process.poll() diff --git a/arduino_testsuite/tests/test.py b/arduino_testsuite/tests/test.py index 255866f..c1fea5c 100644 --- a/arduino_testsuite/tests/test.py +++ b/arduino_testsuite/tests/test.py @@ -1,23 +1,14 @@ import unittest -import random -from arduino_testsuite.testhelper import TestHelper -helper = TestHelper() - -class testArduino(unittest.TestCase): +class TestTheSuite(unittest.TestCase): + """A placeholder for unit tests of this Python program""" def setUp(self): self.seq = range(10) - def test_exitValueHelperOK(self): - self.assertEqual(helper.exitValue(0), 0) - - def test_exitValueHelperError(self): - self.assertEqual(helper.exitValue(-1), 42) - def test_exitValueZero(self): self.assertEqual(0, 0) - + if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/arduino_testsuite/testsuite.py b/arduino_testsuite/testsuite.py index 89bd502..a25ee81 100644 --- a/arduino_testsuite/testsuite.py +++ b/arduino_testsuite/testsuite.py @@ -1,142 +1,118 @@ -#!/usr/bin/env python -# -# Arduino TestSuite to automate unit tests on the Arduino platform -# Copyright (C) 2012 Jeroen Doggen -# More info in "main.py" -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. +""" arduino_testsuite: core code -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +This is currently used to keep the info messages out of the other code +This can later be changed to become a logging interface. -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -# MA 02110-1301, USA. +""" from __future__ import print_function, division # We require Python 2.6+ import os import time -import argparse import datetime import infoprinter -from arduino_testsuite.testhelper import TestHelper +import testhelper from arduino_testsuite.settings import Settings -scriptPath = os.getcwd() - - -helper = TestHelper() - - class TestSuite: - notFinished = True # boolean value - foundTestPath = False - uploadStatus = False - FailedTestList = [] - PassedTestList = [] - failureCount = 0 + """TestSuite class: does the core of the work""" + not_finished = True # boolean value + found_test_path = False + upload_status = False + failed_test_list = [] + passed_test_list = [] + failure_count = 0 line = [] - testList = [] + test_list = [] config = Settings() + scriptpath = os.getcwd() def __init__(self): """Initialize the suite: cli, config file, serial port.""" - self.config.getCliArguments() - self.testList = self.config.readConfigfile() - self.ser = self.config.initSerialPort() + self.config.get_cli_arguments() + self.test_list = self.config.read_testlist_file() + self.ser = self.config.init_serial_port() - def printPlannedTests(self): + def print_planned_tests(self): """Print an overview of all the test that are planned""" - infoprinter.planned_tests(self.testList) + infoprinter.planned_tests(self.test_list) infoprinter.programflow() - def runTests(self, timeout): + def run_tests(self, timeout): """Run all the tests""" - for index, currentTest in enumerate(self.testList): - self.goToTestPath(currentTest) - if (self.foundTestPath): - self.foundTestPath = False + for index, current_test in enumerate(self.test_list): + self.goto_testpath(index, current_test) + if (self.found_test_path): + self.found_test_path = False print("Starting upload...") - self.uploadSketch(timeout) - if (self.uploadStatus == 0): + self.upload_sketch(timeout) + if (self.upload_status == 0): print("Start tests...") - self.analyzeOutput(timeout, currentTest) + self.analyze_output(timeout, current_test) else: - self.addToFailedList(currentTest) + self.failed_test_list.append(current_test) - def goToTestPath(self, currentTest): + def goto_testpath(self, index, current_test): """Go to the folder of the current test""" - infoprinter.setup_info(currentTest) + infoprinter.setup_info(index, current_test) try: - os.chdir(scriptPath) + os.chdir(self.scriptpath) except OSError: print("Error: unable to open the script folder") print("This should never happen...") try: - os.chdir(currentTest) - self.foundTestPath = True + os.chdir(current_test) + self.found_test_path = True except OSError: print("Error: unable to open test folder") print("Check your config file") - self.foundTestPath = False - self.addToFailedList(currentTest) + self.found_test_path = False + self.failed_test_list.append(current_test) - def uploadSketch(self, timeout): + def upload_sketch(self, timeout): """Upload the sketch to the Arduino board""" - self.uploadStatus = helper.timeout_command("scons upload", timeout) - infoprinter.upload_status(self.uploadStatus) + self.upload_status = testhelper.timed_cmd("scons upload", timeout) + infoprinter.upload_status(self.upload_status) - def analyzeOutput(self, timeout, currentTest): + def analyze_output(self, timeout, current_test): """Analyze the test output that is received over the serial port""" start = datetime.datetime.now() - while self.notFinished: - self.readLine(currentTest) + while self.not_finished: + self.read_line(current_test) time.sleep(0.1) now = datetime.datetime.now() if (now - start).seconds > timeout: print ("Test timeout after ", end="") print (timeout, end="") print (" seconds") - self.notFinished = False - self.notFinished = True # to allow the next test to start + self.not_finished = False + self.not_finished = True # to allow the next test to start if (self.line[11] == self.line[25]): - if currentTest not in self.FailedTestList: - self.addToPassedList(currentTest) + if current_test not in self.failed_test_list: + self.passed_test_list.append(current_test) else: - self.FailedTestList.append(currentTest) - self.failureCount = self.failureCount + 1 + self.failed_test_list.append(current_test) + self.failure_count = self.failure_count + 1 - def readLine(self, currentTest): + def read_line(self, current_test): """Read one line of text over the serial port""" try: self.line = self.ser.readline().decode('utf-8')[:-1] print (self.line) - except: + except IOError: print ("unexpectedly lost serial connection") - self.addToFailedList(currentTest) + self.failed_test_list.append(current_test) if(self.line.find("Tests run:") == 0): - self.notFinished = False + self.not_finished = False - def printSummary(self): + def print_summary(self): """Print the summary of all the tests.""" - infoprinter.summary(self.FailedTestList, self.PassedTestList) + infoprinter.summary(self.failed_test_list, self.passed_test_list) - def exitValue(self): + def exit_value(self): """Generate the exit value for the application.""" - return(helper.exitValue(self.failureCount)) - - def addToFailedList(self, currentTest): - """Add the current test to the list of failed tests.""" - self.FailedTestList.append(currentTest) - - def addToPassedList(self, currentTest): - """Add the current test to the list of passed tests.""" - self.PassedTestList.append(currentTest) + if (self.failure_count == 0): + return 0 + else: + return 42