Skip to contentSkip to conversation

toaster: tts fixes

PATCH New Ed Bartosh 1 participant 12 messages Jul 30, 2015

lore
Share & tools
lore

Ed Bartosh

author
#0 lore raw

cover toaster: tts fixes

Hi reviewers,

This is a set of fixes for Toaster TTS testing system from Alex.

The patchset has been reviewed by me. Please review and accept.

The following changes since commit bef724057f1ea81571dd3ac5a9cf862f818434b5:

build: Exit scripts with result of last shell function (2015-07-27 16:29:11 +0100)

are available in the git repository at:

git://git.yoctoproject.org/poky-contrib ed/toaster/submit/adamian/20150715_testfixes
http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=ed/toaster/submit/adamian/20150715_testfixes

Alexandru DAMIAN (11):
toaster: tts: fix pylint warnings
toaster: tts: clean up HTML5 compatible url list toaster tests: gitignore and use absolute path for log file
toaster: tts: improve debugging information
toaster: tts: improve logging in urlcheck.py
toaster: tts: fix startup and cleanup for managed mode
toaster: tts: delete pyc files before the tests start
toaster: tts: delete the database only if created
toaster: tts: make sure to import data
toaster: tts: execute tests in numeric order
toaster: toastergui: run pylint on the toaster files

 .gitignore                            |   3 +
 lib/toaster/contrib/tts/config.py     |  37 +++++++-----
 lib/toaster/contrib/tts/launcher.py   |  35 +++++------
 lib/toaster/contrib/tts/recv.py       |  17 ++++--
 lib/toaster/contrib/tts/runner.py     | 110 ++++++++++++++++++++--------------
 lib/toaster/contrib/tts/scratchpad.py |  20 -------
 lib/toaster/contrib/tts/shellutils.py |  64 ++++++++++----------
 lib/toaster/contrib/tts/tests.py      |  63 ++++++++++---------
 lib/toaster/contrib/tts/urlcheck.py   |  38 ++++++++----
 lib/toaster/contrib/tts/urllist.py    |  83 ++++++++++++-------------
 10 files changed, 250 insertions(+), 220 deletions(-)
 delete mode 100644 lib/toaster/contrib/tts/scratchpad.py

--
Regards,
Ed

author
#1 lore raw

PATCH 1/11 toaster: tts: fix pylint warnings

From: Alexandru DAMIAN <[email protected]>

This patch brings TTS to the pylint coding standards. Pylint was run with some disables:

disable=logging-too-many-args,line-too-long,missing-docstring

and achieved

Your code has been rated at 10.00/10

There are no functional changes.

---
 lib/toaster/contrib/tts/config.py     | 37 ++++++++------
 lib/toaster/contrib/tts/launcher.py   | 35 +++++++-------
 lib/toaster/contrib/tts/recv.py       | 13 +++--
 lib/toaster/contrib/tts/runner.py     | 87 +++++++++++++++++----------------
 lib/toaster/contrib/tts/scratchpad.py | 20 --------
 lib/toaster/contrib/tts/shellutils.py | 64 +++++++++++++------------
 lib/toaster/contrib/tts/tests.py      | 43 ++++++++---------
 lib/toaster/contrib/tts/urlcheck.py   | 29 ++++++-----
 lib/toaster/contrib/tts/urllist.py    | 90 +++++++++++++++++------------------
 9 files changed, 208 insertions(+), 210 deletions(-)
 delete mode 100644 lib/toaster/contrib/tts/scratchpad.py
lib/toaster/contrib/tts/config.py +22 -15
index c0e0536..40d45f3 100644
@@ -28,42 +28,48 @@ LOGDIR = "log"
 SETTINGS_FILE = os.path.join(os.path.dirname(__file__), "settings.json")
 TEST_DIR_NAME = "tts_testdir"
 
+DEBUG = True
+
 OWN_PID = os.getpid()
 
 W3C_VALIDATOR = "http://icarus.local/w3c-validator/check?doctype=HTML5&uri="
 
-#TODO assign port dynamically
-TOASTER_PORT=56789
+TOASTER_PORT = 56789
+
+TESTDIR = None
 
 #we parse the w3c URL to know where to connect
 
 import urlparse
 
 def get_public_ip():
-    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-    p = urlparse.urlparse("http://icarus.local/w3c-validator/check?doctype=HTML5&uri=")
-    s.connect(( p.netloc, 80 if p.port is None else p.port))
-    hn = s.getsockname()[0]
-    s.close()
-    return hn
+    temp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    parsed_url = urlparse.urlparse("http://icarus.local/w3c-validator/check?doctype=HTML5&uri=")
+    temp_socket.connect((parsed_url.netloc, 80 if parsed_url.port is None else parsed_url.port))
+    public_ip = temp_socket.getsockname()[0]
+    temp_socket.close()
+    return public_ip
 
-TOASTER_BASEURL="http://%s:%d/" % (get_public_ip(), TOASTER_PORT)
+TOASTER_BASEURL = "http://%s:%d/" % (get_public_ip(), TOASTER_PORT)
 
 
 OWN_EMAIL_ADDRESS = "Toaster Testing Framework <[email protected]>"
 REPORT_EMAIL_ADDRESS = "[email protected]"
 
 # make sure we have the basic logging infrastructure
+
+#pylint: disable=invalid-name
+# we disable the invalid name because the module-level "logger" is used througout bitbake
 logger = logging.getLogger("toastertest")
-__console = logging.StreamHandler(sys.stdout)
-__console.setFormatter(logging.Formatter("%(asctime)s %(levelname)s: %(message)s"))
-logger.addHandler(__console)
+__console__ = logging.StreamHandler(sys.stdout)
+__console__.setFormatter(logging.Formatter("%(asctime)s %(levelname)s: %(message)s"))
+logger.addHandler(__console__)
 logger.setLevel(logging.DEBUG)
 
 
 # singleton file names
-LOCKFILE="/tmp/ttf.lock"
-BACKLOGFILE=os.path.join(os.path.dirname(__file__), "backlog.txt")
+LOCKFILE = "/tmp/ttf.lock"
+BACKLOGFILE = os.path.join(os.path.dirname(__file__), "backlog.txt")
 
 # task states
 def enum(*sequential, **named):
@@ -73,7 +79,8 @@ def enum(*sequential, **named):
     return type('Enum', (), enums)
 
 
-class TASKS:
+class TASKS(object):
+    #pylint: disable=too-few-public-methods
     PENDING = "PENDING"
     INPROGRESS = "INPROGRESS"
     DONE = "DONE"
lib/toaster/contrib/tts/launcher.py +18 -17
index 90c6d95..e5794c1 100755
@@ -31,13 +31,11 @@ import smtplib
 # Import the email modules we'll need
 from email.mime.text import MIMEText
 
-DEBUG=True
-
 def _take_lockfile():
     return shellutils.lockfile(shellutils.mk_lock_filename())
 
 
-def read_next_task_by_state(task_state, task_name = None):
+def read_next_task_by_state(task_state, task_name=None):
     if not os.path.exists(os.path.join(os.path.dirname(__file__), config.BACKLOGFILE)):
         return None
     os.rename(config.BACKLOGFILE, config.BACKLOGFILE + ".tmp")
@@ -56,28 +54,28 @@ def read_next_task_by_state(task_state, task_name = None):
     os.remove(config.BACKLOGFILE + ".tmp")
     return task
 
-def send_report(task_name, plaintext, errtext = None):
+def send_report(task_name, plaintext, errtext=None):
     if errtext is None:
         msg = MIMEText(plaintext)
     else:
         if plaintext is None:
-            plaintext=""
+            plaintext = ""
         msg = MIMEText("--STDOUT dump--\n\n%s\n\n--STDERR dump--\n\n%s" % (plaintext, errtext))
 
     msg['Subject'] = "[review-request] %s - smoke test results" % task_name
     msg['From'] = config.OWN_EMAIL_ADDRESS
     msg['To'] = config.REPORT_EMAIL_ADDRESS
 
-    s = smtplib.SMTP("localhost")
-    s.sendmail(config.OWN_EMAIL_ADDRESS, [config.REPORT_EMAIL_ADDRESS], msg.as_string())
-    s.quit()
+    smtp_connection = smtplib.SMTP("localhost")
+    smtp_connection.sendmail(config.OWN_EMAIL_ADDRESS, [config.REPORT_EMAIL_ADDRESS], msg.as_string())
+    smtp_connection.quit()
 
-if __name__ == "__main__":
+def main():
     # we don't do anything if we have another instance of us running
-    lf = _take_lockfile()
+    lock_file = _take_lockfile()
 
-    if lf is None:
-        if DEBUG:
+    if lock_file is None:
+        if config.DEBUG:
             print("Concurrent script in progress, exiting")
         sys.exit(1)
 
@@ -88,13 +86,16 @@ if __name__ == "__main__":
         out = None
         try:
             out = shellutils.run_shell_cmd("%s %s" % (os.path.join(os.path.dirname(__file__), "runner.py"), next_task))
-            pass
-        except ShellCmdException as e:
-            print("Failed while running the test runner: %s", e)
-            errtext = e.__str__()
+        except ShellCmdException as exc:
+            print("Failed while running the test runner: %s", exc)
+            errtext = exc.__str__()
         send_report(next_task, out, errtext)
         read_next_task_by_state(config.TASKS.INPROGRESS, next_task)
     else:
         print("No task")
 
-    shellutils.unlockfile(lf)
+    shellutils.unlockfile(lock_file)
+
+
+if __name__ == "__main__":
+    main()
lib/toaster/contrib/tts/recv.py +9 -4
index 168294a..2faf8d0 100755
@@ -26,7 +26,6 @@
 
 from __future__ import print_function
 import sys, os, config, shellutils
-from shellutils import ShellCmdException
 
 from email.parser import Parser
 
@@ -34,9 +33,13 @@ def recv_mail(datastring):
     headers = Parser().parsestr(datastring)
     return headers['subject']
 
+def main():
+    lock_file = shellutils.lockfile(shellutils.mk_lock_filename(), retry=True)
 
-if __name__ == "__main__":
-    lf = shellutils.lockfile(shellutils.mk_lock_filename(), retry = True)
+    if lock_file is None:
+        if config.DEBUG:
+            print("Concurrent script in progress, exiting")
+        sys.exit(1)
 
     subject = recv_mail(sys.stdin.read())
 
@@ -47,5 +50,7 @@ if __name__ == "__main__":
             line = "%s|%s\n" % (task_name, config.TASKS.PENDING)
             fout.write(line)
 
-    shellutils.unlockfile(lf)
+    shellutils.unlockfile(lock_file)
 
+if __name__ == "__main__":
+    main()
lib/toaster/contrib/tts/runner.py +45 -42

177 lines not on this page · raw message

lib/toaster/contrib/tts/scratchpad.py deleted +0 -20
deleted file mode 100644
index b276fb5..0000000
@@ -1,20 +0,0 @@
-import config
-
-# Code testing section
-def _code_test():
-    def callback_writeeventlog(opt, opt_str, value, parser):
-        if len(parser.rargs) < 1 or parser.rargs[0].startswith("-"):
-            value = ""
-        else:
-            value = parser.rargs[0]
-            del parser.rargs[0]
-
-        setattr(parser.values, opt.dest, value)
-
-    parser = optparse.OptionParser()
-    parser.add_option("-w", "--write-log", help = "Writes the event log of the build to a bitbake event json file.",
-                       action = "callback", callback=callback_writeeventlog, dest = "writeeventlog")
-
-    options, targets = parser.parse_args(sys.argv)
-
-    print (options, targets)
lib/toaster/contrib/tts/shellutils.py +33 -31

118 lines not on this page · raw message

lib/toaster/contrib/tts/tests.py +20 -23

83 lines not on this page · raw message

lib/toaster/contrib/tts/urlcheck.py +17 -12
index 86d7caa..8514de8 100644
@@ -2,40 +2,45 @@ from __future__ import print_function
 import sys
 
 import httplib2
-import time
 
 import config
 import urllist
 
 
-# TODO: turn to a test
 def validate_html5(url):
-    h = httplib2.Http(".cache")
+    http_client = httplib2.Http(None)
     status = "Failed"
     errors = -1
     warnings = -1
 
-    # TODO: the w3c-validator must be a configurable setting
     urlrequest = config.W3C_VALIDATOR+url
+
+    # pylint: disable=broad-except
+    # we disable the broad-except because we want to actually catch all possible exceptions
     try:
-        resp, content = h.request(urlrequest, "HEAD")
+        resp, _ = http_client.request(urlrequest, "HEAD")
         if resp['x-w3c-validator-status'] != "Abort":
             status = resp['x-w3c-validator-status']
             errors = int(resp['x-w3c-validator-errors'])
             warnings = int(resp['x-w3c-validator-warnings'])
-    except Exception as e:
-        config.logger.warn("Failed validation call: %s" % e.__str__())
+    except Exception as exc:
+        config.logger.warn("Failed validation call: %s", exc)
     return (status, errors, warnings)
 
-if __name__ == "__main__":
-    print("Testing %s with %s" % (config.TOASTER_BASEURL, config.W3C_VALIDATOR))
 
-    def print_validation(url):
-        status, errors, warnings = validate_html5(url)
-        config.logger.error("url %s is %s\terrors %s warnings %s (check at %s)" % (url, status, errors, warnings, config.W3C_VALIDATOR+url))
+def print_validation(url):
+    status, errors, warnings = validate_html5(url)
+    config.logger.error("url %s is %s\terrors %s warnings %s (check at %s)", url, status, errors, warnings, config.W3C_VALIDATOR+url)
+
+
+def main():
+    print("Testing %s with %s" % (config.TOASTER_BASEURL, config.W3C_VALIDATOR))
 
     if len(sys.argv) > 1:
         print_validation(sys.argv[1])
     else:
         for url in urllist.URLS:
             print_validation(config.TOASTER_BASEURL+url)
+
+if __name__ == "__main__":
+    main()
lib/toaster/contrib/tts/urllist.py +44 -46

92 lines not on this page · raw message

Signature · 1 line
2.1.4
author
#3 lore raw

PATCH 3/11 toaster tests: gitignore and use absolute path for log file

From: Alexandru DAMIAN <[email protected]>

gitignore the cache directory created by the http client

the log file for tests is already set up as an absolute path, so no need to recompute the path

---
 .gitignore                      | 3 +++
 lib/toaster/contrib/tts/recv.py | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)
.gitignore +3 -0
index 5adf4d1..8ca4b5d 100644
@@ -12,3 +12,6 @@ venv/
 doc/bitbake-user-manual/bitbake-user-manual.html
 doc/bitbake-user-manual/bitbake-user-manual.pdf
 doc/bitbake-user-manual/bitbake-user-manual.tgz
+lib/toaster/contrib/tts/backlog.txt
+lib/toaster/contrib/tts/log/*
+lib/toaster/contrib/tts/.cache/*
lib/toaster/contrib/tts/recv.py +2 -2
index 2faf8d0..07efdac 100755
@@ -25,7 +25,7 @@
 # |[full/path]/recv.py
 
 from __future__ import print_function
-import sys, os, config, shellutils
+import sys, config, shellutils
 
 from email.parser import Parser
 
@@ -46,7 +46,7 @@ def main():
     subject_parts = subject.split()
     if "[review-request]" in subject_parts:
         task_name = subject_parts[subject_parts.index("[review-request]") + 1]
-        with open(os.path.join(os.path.dirname(__file__), config.BACKLOGFILE), "a") as fout:
+        with open(config.BACKLOGFILE, "a") as fout:
             line = "%s|%s\n" % (task_name, config.TASKS.PENDING)
             fout.write(line)
 
Signature · 1 line
2.1.4
author
#4 lore raw

PATCH 4/11 toaster: tts: improve debugging information

In reply to Ed Bartosh

From: Alexandru DAMIAN <[email protected]>

We add debug information, and exception handling as to make it easy to figure out what is going on when tests fail on automatic start.

---
 lib/toaster/contrib/tts/runner.py | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
lib/toaster/contrib/tts/runner.py +12 -1
index 809fb35..dac632c 100755
@@ -62,7 +62,10 @@ def set_up_test_branch(settings, branch_name):
     # creates the host dir
     if os.path.exists(testdir):
         raise Exception("Test dir '%s'is already there, aborting" % testdir)
-    os.mkdir(testdir)
+
+    # may raise OSError, is to be handled by the caller
+    os.makedirs(testdir)
+
 
     # copies over the .git from the localclone
     run_shell_cmd("cp -a '%s'/.git '%s'" % (settings['localclone'], testdir))
@@ -171,12 +174,20 @@ def read_settings():
 def clean_up(testdir):
     run_shell_cmd("rm -rf -- '%s'" % testdir)
 
+def dump_info(settings, options, args):
+    """ detailed information about current run configuration, for debugging purposes.
+    """
+    config.logger.debug("Settings:\n%s\nOptions:\n%s\nArguments:\n%s\n", settings, options, args)
+
 def main():
     (options, args) = validate_args()
 
     settings = read_settings()
     need_cleanup = False
 
+    # dump debug info
+    dump_info(settings, options, args)
+
     testdir = None
     no_failures = 1
     try:
Signature · 1 line
2.1.4
author
#5 lore raw

PATCH 5/11 toaster: tts: improve logging in urlcheck.py

In reply to Ed Bartosh

From: Alexandru DAMIAN <[email protected]>

This patch improves logging in the urlcheck.py. It allows properly running just HTML5 tests outside the test suite.

---
 lib/toaster/contrib/tts/urlcheck.py | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
lib/toaster/contrib/tts/urlcheck.py +8 -1
index 8514de8..0820f82 100644
@@ -2,11 +2,12 @@ from __future__ import print_function
 import sys
 
 import httplib2
-
 import config
 import urllist
 
 
+config.logger.info("Testing %s with %s", config.TOASTER_BASEURL, config.W3C_VALIDATOR)
+
 def validate_html5(url):
     http_client = httplib2.Http(None)
     status = "Failed"
@@ -23,6 +24,12 @@ def validate_html5(url):
             status = resp['x-w3c-validator-status']
             errors = int(resp['x-w3c-validator-errors'])
             warnings = int(resp['x-w3c-validator-warnings'])
+
+            if status == 'Invalid':
+                config.logger.warn("Failed %s is %s\terrors %s warnings %s (check at %s)", url, status, errors, warnings, urlrequest)
+            else:
+                config.logger.debug("OK! %s", url)
+
     except Exception as exc:
         config.logger.warn("Failed validation call: %s", exc)
     return (status, errors, warnings)
Signature · 1 line
2.1.4
author
#6 lore raw

PATCH 6/11 toaster: tts: fix startup and cleanup for managed mode

In reply to Ed Bartosh

From: Alexandru DAMIAN <[email protected]>

This patch fixes the toaster startup and database cleanup for managed mode. It is needed because the toaster script thinks it has been called with "source" instead of being executed as independent script if not called through bash.

---
 lib/toaster/contrib/tts/runner.py | 1 +
 lib/toaster/contrib/tts/tests.py  | 7 ++++---
 2 files changed, 5 insertions(+), 3 deletions(-)
lib/toaster/contrib/tts/runner.py +1 -0
index dac632c..3fd1b66 100755
@@ -122,6 +122,7 @@ def execute_tests(dir_under_test, testname):
     # we disable the broad-except because we want to actually catch all possible exceptions
     try:
         config.logger.debug("Discovered test clases: %s", pprint.pformat(tests))
+        unittest.installHandler()
         suite = unittest.TestSuite()
         loader = unittest.TestLoader()
         result = unittest.TestResult()
lib/toaster/contrib/tts/tests.py +4 -3
index eb91947..fd6aa3b 100644
@@ -76,7 +76,7 @@ class TestHTML5Compliance(unittest.TestCase):
             setup.expect(r"Enter your option: ")
             setup.sendline('0')
 
-        self.child = pexpect.spawn("%s/bitbake/bin/toaster webport=%d nobrowser" % (config.TESTDIR, config.TOASTER_PORT))
+        self.child = pexpect.spawn("bash", ["%s/bitbake/bin/toaster" % config.TESTDIR, "webport=%d" % config.TOASTER_PORT, "nobrowser"], cwd=self.crtdir)
         self.child.logfile = sys.stdout
         self.child.expect("Toaster is now running. You can stop it with Ctrl-C")
 
@@ -101,5 +101,6 @@ class TestHTML5Compliance(unittest.TestCase):
             self.child.kill(signal.SIGINT)
             time.sleep(1)
         os.chdir(self.origdir)
-#        if os.path.exists(os.path.join(self.crtdir, "toaster.sqlite")):
-#            os.remove(os.path.join(self.crtdir, "toaster.sqlite"))
+        toaster_sqlite_path = os.path.join(self.crtdir, "toaster.sqlite")
+        if os.path.exists(toaster_sqlite_path):
+            os.remove(toaster_sqlite_path)
Signature · 1 line
2.1.4
author
#8 lore raw

PATCH 8/11 toaster: tts: delete the database only if created

In reply to Ed Bartosh

From: Alexandru DAMIAN <[email protected]>

To allow the tests to run on different databases (in case of manual runs), the HTML5 test will only delete the database file if it was created in the setUp.

---
 lib/toaster/contrib/tts/tests.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
lib/toaster/contrib/tts/tests.py +3 -1
index fd6aa3b..8d19647 100644
@@ -59,8 +59,10 @@ class TestHTML5Compliance(unittest.TestCase):
     def setUp(self):
         self.origdir = os.getcwd()
         self.crtdir = os.path.dirname(config.TESTDIR)
+        self.cleanup_database = False
         os.chdir(self.crtdir)
         if not os.path.exists(os.path.join(self.crtdir, "toaster.sqlite")):
+            self.cleanup_database = False
             run_shell_cmd("%s/bitbake/lib/toaster/manage.py syncdb --noinput" % config.TESTDIR)
             run_shell_cmd("%s/bitbake/lib/toaster/manage.py migrate orm" % config.TESTDIR)
             run_shell_cmd("%s/bitbake/lib/toaster/manage.py migrate bldcontrol" % config.TESTDIR)
@@ -102,5 +104,5 @@ class TestHTML5Compliance(unittest.TestCase):
             time.sleep(1)
         os.chdir(self.origdir)
         toaster_sqlite_path = os.path.join(self.crtdir, "toaster.sqlite")
-        if os.path.exists(toaster_sqlite_path):
+        if self.cleanup_database and os.path.exists(toaster_sqlite_path):
             os.remove(toaster_sqlite_path)
Signature · 1 line
2.1.4
author
#9 lore raw

PATCH 9/11 toaster: tts: make sure to import data

In reply to Ed Bartosh

From: Alexandru DAMIAN <[email protected]>

Importing data from the layer index should be part of the setup because otherwise we have no reliable database configuration.

This patch selects the first option for importing the database configuration file.

---
 lib/toaster/contrib/tts/tests.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
lib/toaster/contrib/tts/tests.py +2 -1
index 8d19647..9acef46 100644
@@ -62,11 +62,12 @@ class TestHTML5Compliance(unittest.TestCase):
         self.cleanup_database = False
         os.chdir(self.crtdir)
         if not os.path.exists(os.path.join(self.crtdir, "toaster.sqlite")):
-            self.cleanup_database = False
+            self.cleanup_database = True
             run_shell_cmd("%s/bitbake/lib/toaster/manage.py syncdb --noinput" % config.TESTDIR)
             run_shell_cmd("%s/bitbake/lib/toaster/manage.py migrate orm" % config.TESTDIR)
             run_shell_cmd("%s/bitbake/lib/toaster/manage.py migrate bldcontrol" % config.TESTDIR)
             run_shell_cmd("%s/bitbake/lib/toaster/manage.py loadconf %s/meta-yocto/conf/toasterconf.json" % (config.TESTDIR, config.TESTDIR))
+            run_shell_cmd("%s/bitbake/lib/toaster/manage.py lsupdates" % config.TESTDIR)
 
             setup = pexpect.spawn("%s/bitbake/lib/toaster/manage.py checksettings" % config.TESTDIR)
             setup.logfile = sys.stdout
Signature · 1 line
2.1.4
author
#2 lore raw

PATCH 2/11 toaster: tts: clean up HTML5 compatible url list

In reply to Ed Bartosh

From: Alexandru DAMIAN <[email protected]>

This patch cleans up the list of URLs that are tested for HTML5 compatibility using the w3c-validator. It removes the URLs that are no longer in use, and the AJAX-only URLs that return JSON content.

---
 lib/toaster/contrib/tts/urllist.py | 7 -------
 1 file changed, 7 deletions(-)
lib/toaster/contrib/tts/urllist.py +0 -7
index 3f3a7c2..6db9ffc 100644
@@ -17,7 +17,6 @@ URLS = [
     'toastergui/build/1/package_included_reverse_dependencies/1/1',
     'toastergui/build/1/target/1',
     'toastergui/build/1/target/1/targetpkg',
-    'toastergui/dentries/build/1/target/1',
     'toastergui/build/1/target/1/dirinfo',
     'toastergui/build/1/target/1/dirinfo_filepath/_/bin/bash',
     'toastergui/build/1/configuration',
@@ -28,19 +27,13 @@ URLS = [
     'toastergui/build/1/target/1/packagefile/1',
     'toastergui/newproject/',
     'toastergui/projects/',
-    'toastergui/project/',
     'toastergui/project/1',
     'toastergui/project/1/configuration',
     'toastergui/project/1/builds/',
     'toastergui/project/1/layers/',
     'toastergui/project/1/layer/1',
-    'toastergui/project/1/layer/',
     'toastergui/project/1/importlayer',
     'toastergui/project/1/targets/',
     'toastergui/project/1/machines/',
-    'toastergui/xhr_configvaredit/1',
-    'toastergui/xhr_importlayer/',
-    'toastergui/xhr_updatelayer/',
-    'toastergui/project/1/buildrequest/1',
     'toastergui/',
 ]
Signature · 1 line
2.1.4
author
#7 lore raw

PATCH 7/11 toaster: tts: delete pyc files before the tests start

In reply to Ed Bartosh

From: Alexandru DAMIAN <[email protected]>

There may be leftover *.pyc files from previous code runs in the current checkout directory, so we delete everything before starting the tests, to make sure that we actually testing the current checkout.

---
 lib/toaster/contrib/tts/runner.py | 4 ++++
 1 file changed, 4 insertions(+)
lib/toaster/contrib/tts/runner.py +4 -0
index 3fd1b66..6fc3e77 100755
@@ -200,6 +200,10 @@ def main():
             testdir = set_up_test_branch(settings, args[0]) # we expect a branch name as first argument
 
         config.TESTDIR = testdir    # we let tests know where to run
+
+        # ensure that the test dir only contains no *.pyc leftovers
+        run_shell_cmd("find '%s' -type f -name *.pyc -exec rm {} \;" % testdir)
+
         no_failures = execute_tests(testdir, options.singletest)
 
     except ShellCmdException as exc:
Signature · 1 line
2.1.4
author
#10 lore raw

PATCH 10/11 toaster: tts: execute tests in numeric order

In reply to Ed Bartosh

From: Alexandru DAMIAN <[email protected]>

As the tests are verifying different type of the functionality, it is usually the case that a failing early test will completely make the subsequent tests failing, e.g. if the system cannot start due to a bug, there is little point in testing other functions.

In order to prevent uneeded test runs, and to generate repeatable test patterns, the test cases have now a numeric order in the class name (e.g. Test01XXX). The tests are executed in this order, and the first test failing will stop the test run.

---
 lib/toaster/contrib/tts/runner.py | 11 +++++++----
 lib/toaster/contrib/tts/tests.py  |  6 +++---
 2 files changed, 10 insertions(+), 7 deletions(-)
lib/toaster/contrib/tts/runner.py +7 -4
index 6fc3e77..bed6651 100755
@@ -31,7 +31,7 @@ from __future__ import print_function
 import sys, os
 import unittest, importlib
 import logging, pprint, json
-
+import re
 from shellutils import ShellCmdException, mkdirhier, run_shell_cmd
 
 import config
@@ -121,13 +121,16 @@ def execute_tests(dir_under_test, testname):
     # pylint: disable=broad-except
     # we disable the broad-except because we want to actually catch all possible exceptions
     try:
+        # sorting the tests by the numeric order in the class name
+        tests = sorted(tests, key=lambda x: int(re.search(r"[0-9]+", x[1]).group(0)))
         config.logger.debug("Discovered test clases: %s", pprint.pformat(tests))
         unittest.installHandler()
         suite = unittest.TestSuite()
         loader = unittest.TestLoader()
         result = unittest.TestResult()
-        for module_file, name in tests:
-            suite.addTest(loader.loadTestsFromName("%s.%s" % (module_file, name)))
+        result.failfast = True
+        for module_file, test_name in tests:
+            suite.addTest(loader.loadTestsFromName("%s.%s" % (module_file, test_name)))
         config.logger.info("Running %d test(s)", suite.countTestCases())
         suite.run(result)
 
@@ -202,7 +205,7 @@ def main():
         config.TESTDIR = testdir    # we let tests know where to run
 
         # ensure that the test dir only contains no *.pyc leftovers
-        run_shell_cmd("find '%s' -type f -name *.pyc -exec rm {} \;" % testdir)
+        run_shell_cmd("find '%s' -type f -name *.pyc -exec rm {} \\;" % testdir)
 
         no_failures = execute_tests(testdir, options.singletest)
 
lib/toaster/contrib/tts/tests.py +3 -3
index 9acef46..3a4eed1 100644
@@ -30,7 +30,7 @@ import config
 import pexpect
 import sys, os, signal, time
 
-class TestPyCompilable(unittest.TestCase):
+class Test00PyCompilable(unittest.TestCase):
     ''' Verifies that all Python files are syntactically correct '''
     def test_compile_file(self):
         try:
@@ -38,7 +38,7 @@ class TestPyCompilable(unittest.TestCase):
         except ShellCmdException as exc:
             self.fail("Error compiling python files: %s" % (exc))
 
-class TestPySystemStart(unittest.TestCase):
+class Test01PySystemStart(unittest.TestCase):
     ''' Attempts to start Toaster, verify that it is succesfull, and stop it '''
     def setUp(self):
         run_shell_cmd("bash -c 'rm -f build/*log'")
@@ -55,7 +55,7 @@ class TestPySystemStart(unittest.TestCase):
         except ShellCmdException as exc:
             self.fail("Failed starting managed mode: %s" % (exc))
 
-class TestHTML5Compliance(unittest.TestCase):
+class Test02HTML5Compliance(unittest.TestCase):
     def setUp(self):
         self.origdir = os.getcwd()
         self.crtdir = os.path.dirname(config.TESTDIR)
Signature · 1 line
2.1.4
author
#11 lore raw

PATCH 11/11 toaster: toastergui: run pylint on the toaster files

In reply to Ed Bartosh

From: Alexandru DAMIAN <[email protected]>

This patch enables pylint running on the toaster files, showing only the errors. This enables spotting common mistakes in the toaster python files.

---
 lib/toaster/contrib/tts/tests.py | 6 ++++++
 1 file changed, 6 insertions(+)
lib/toaster/contrib/tts/tests.py +6 -0
index 3a4eed1..c510ebb 100644
@@ -38,6 +38,12 @@ class Test00PyCompilable(unittest.TestCase):
         except ShellCmdException as exc:
             self.fail("Error compiling python files: %s" % (exc))
 
+    def test_pylint_file(self):
+        try:
+            run_shell_cmd(r"find . -iname \"*\.py\" -type f -print0 | PYTHONPATH=${PYTHONPATH}:. xargs -r -0 -n1 pylint --load-plugins pylint_django -E --reports=n 2>&1", cwd=config.TESTDIR + "/bitbake/lib/toaster")
+        except ShellCmdException as exc:
+            self.fail("Pylint fails: %s\n" % exc)
+
 class Test01PySystemStart(unittest.TestCase):
     ''' Attempts to start Toaster, verify that it is succesfull, and stop it '''
     def setUp(self):
Signature · 1 line
2.1.4