Index: README
===================================================================
--- README	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ README	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -29,6 +29,26 @@
 To build and install:
 
- $ ./waf configure --prefix=$HOME/development/rtems/4.11
+ $ ./waf configure --prefix=$HOME/development/rtems/5
  $ ./waf build install
+
+Testing
+-------
+
+To the run the tests build then enter:
+
+ $ ./waf test
+
+Python
+------
+
+The RTEMS Tools supports python3 and python2. The commands look for python3,
+then python2 and finally python and use the first it finds.
+
+You can forced a specific version for testing by setting the environment
+variable 'RTEMS_PYTHON_OVERRIDE' to the python you want to use. For example:
+
+ $ export RTEMS_PYTHON_OVERRIDE=python2
+
+will use python2.
 
 Waf
@@ -38,7 +58,2 @@
 
  http://code.google.com/p/waf/
-
-Simple instructions on How to set up Waf is here:
-
- http://www.rtems.org/ftp/pub/rtems/people/chrisj/rtl/rtems-linker/waf.html
-
Index: rtemstoolkit/__init__.py
===================================================================
--- rtemstoolkit/__init__.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/__init__.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -47,19 +47,11 @@
        'version']
 
-from . import check
-from . import config
-from . import configuration
-from . import error
-from . import execute
-from . import git
-from . import host
-from . import log
-from . import macros
-from . import mailer
-from . import options
-from . import path
-from . import reraise
-from . import rtems
-from . import stacktraces
-from . import textbox
-from . import version
+args = {
+    'config': ['--file', 'tester/rtems/version.cfg',
+               '--jobs', 'half',
+               '--no-clean'],
+    'mailer': ['--smtp-host', '1.2.3.4',
+               '--mail-to',   'foo@bar.none',
+               '--mail-from', 'me@here.there']
+
+}
Index: rtemstoolkit/check.py
===================================================================
--- rtemstoolkit/check.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/check.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -37,22 +37,10 @@
 import os
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import error
-    from . import execute
-    from . import log
-    from . import options
-    from . import path
-    from . import version
-except (ValueError, SystemError):
-    import error
-    import execute
-    import log
-    import options
-    import path
-    import version
+from rtemstoolkit import error
+from rtemstoolkit import execute
+from rtemstoolkit import log
+from rtemstoolkit import options
+from rtemstoolkit import path
+from rtemstoolkit import version
 
 def _check_none(_opts, macro, value, constraint):
@@ -164,10 +152,10 @@
 
 
-def run():
+def run(args):
     import sys
     try:
-        _opts = options.command_line(argv = sys.argv)
+        _opts = options.command_line(argv = args)
         options.load(_opts)
-        log.notice('RTEMS Source Builder - Check, v%s' % (version.string()))
+        log.notice('RTEMS Toolkit - Check, v%s' % (version.string()))
         if host_setup(_opts):
             print('Environment is ok')
@@ -189,3 +177,3 @@
 
 if __name__ == '__main__':
-    run()
+    run(['tester'])
Index: rtemstoolkit/config.py
===================================================================
--- rtemstoolkit/config.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/config.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -45,22 +45,10 @@
 import sys
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import error
-    from . import execute
-    from . import host
-    from . import log
-    from . import options
-    from . import path
-except (ValueError, SystemError):
-    import error
-    import execute
-    import host
-    import log
-    import options
-    import path
+from rtemstoolkit import error
+from rtemstoolkit import execute
+from rtemstoolkit import host
+from rtemstoolkit import log
+from rtemstoolkit import options
+from rtemstoolkit import path
 
 def _check_bool(value):
Index: rtemstoolkit/darwin.py
===================================================================
--- rtemstoolkit/darwin.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/darwin.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -36,12 +36,5 @@
 import os
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import execute
-except (ValueError, SystemError):
-    import execute
+from rtemstoolkit import execute
 
 def cpus():
Index: rtemstoolkit/freebsd.py
===================================================================
--- rtemstoolkit/freebsd.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/freebsd.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -36,14 +36,6 @@
 import os
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import check
-    from . import execute
-except (ValueError, SystemError):
-    import check
-    import execute
+from rtemstoolkit import check
+from rtemstoolkit import execute
 
 def cpus():
Index: rtemstoolkit/git.py
===================================================================
--- rtemstoolkit/git.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/git.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -32,18 +32,8 @@
 import os
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import error
-    from . import execute
-    from . import log
-    from . import path
-except (ValueError, SystemError):
-    import error
-    import execute
-    import log
-    import path
+from rtemstoolkit import error
+from rtemstoolkit import execute
+from rtemstoolkit import log
+from rtemstoolkit import path
 
 class repo:
@@ -221,5 +211,5 @@
 if __name__ == '__main__':
     import sys
-    import options
+    from rtemstoolkit import options
     long_opts = {
        # key              macro        handler   param  defs   init
Index: rtemstoolkit/host.py
===================================================================
--- rtemstoolkit/host.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/host.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -37,12 +37,5 @@
 import os
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import error
-except (ValueError, SystemError):
-    import error
+from rtemstoolkit import error
 
 is_windows = False
@@ -114,5 +107,4 @@
 if __name__ == '__main__':
     import pprint
-    pprint.pprint(platform())
     _load()
     print('Name      : %s' % (name))
Index: rtemstoolkit/linux.py
===================================================================
--- rtemstoolkit/linux.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/linux.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -37,14 +37,6 @@
 import platform
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import execute
-    from . import path
-except (ValueError, SystemError):
-    import execute
-    import path
+from rtemstoolkit import execute
+from rtemstoolkit import path
 
 def cpus():
Index: rtemstoolkit/log.py
===================================================================
--- rtemstoolkit/log.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/log.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -39,12 +39,5 @@
 import threading
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import error
-except (ValueError, SystemError):
-    import error
+from rtemstoolkit import error
 
 #
Index: rtemstoolkit/macros.py
===================================================================
--- rtemstoolkit/macros.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/macros.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -41,16 +41,7 @@
 import string
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import error
-    from . import log
-    from . import path
-except (ValueError, SystemError):
-    import error
-    import log
-    import path
+from rtemstoolkit import error
+from rtemstoolkit import log
+from rtemstoolkit import path
 
 #
Index: rtemstoolkit/mailer.py
===================================================================
--- rtemstoolkit/mailer.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/mailer.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -39,16 +39,7 @@
 import socket
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import error
-    from . import options
-    from . import path
-except (ValueError, SystemError):
-    import error
-    import options
-    import path
+from rtemstoolkit import error
+from rtemstoolkit import options
+from rtemstoolkit import path
 
 _options = {
@@ -162,9 +153,18 @@
 if __name__ == '__main__':
     import sys
+    from rtemstoolkit import macros
     optargs = {}
+    rtdir = 'rtemstoolkit'
+    defaults = '%s/defaults.mc' % (rtdir)
     append_options(optargs)
-    opts = options.load(sys.argv, optargs = optargs, defaults = 'defaults.mc')
+    opts = options.command_line(base_path = '.',
+                                argv = sys.argv,
+                                optargs = optargs,
+                                defaults = macros.macros(name = defaults, rtdir = rtdir),
+                                command_path = '.')
+    options.load(opts)
     m = mail(opts)
     print('From: %s' % (m.from_address()))
     print('SMTP Host: %s' % (m.smtp_host()))
-    m.send(m.from_address(), 'Test mailer.py', 'This is a test')
+    if '--mail' in sys.argv:
+        m.send(m.from_address(), 'Test mailer.py', 'This is a test')
Index: rtemstoolkit/netbsd.py
===================================================================
--- rtemstoolkit/netbsd.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/netbsd.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -27,10 +27,6 @@
 import os
 
-try:
-    from . import check
-    from . import execute
-except (ValueError, SystemError):
-    import check
-    import execute
+from rtemstoolkit import check
+from rtemstoolkit import execute
 
 def cpus():
Index: rtemstoolkit/options.py
===================================================================
--- rtemstoolkit/options.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/options.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -43,26 +43,12 @@
 import sys
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import error
-    from . import execute
-    from . import git
-    from . import host
-    from . import log
-    from . import macros
-    from . import path
-    from . import version
-except (ValueError, SystemError):
-    import error
-    import execute
-    import git
-    import host
-    import log
-    import macros
-    import path
-    import version
+from rtemstoolkit import error
+from rtemstoolkit import execute
+from rtemstoolkit import git
+from rtemstoolkit import host
+from rtemstoolkit import log
+from rtemstoolkit import macros
+from rtemstoolkit import path
+from rtemstoolkit import version
 
 basepath = 'tb'
Index: rtemstoolkit/path.py
===================================================================
--- rtemstoolkit/path.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/path.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -42,14 +42,6 @@
 import string
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import error
-    from . import log
-except (ValueError, SystemError):
-    import error
-    import log
+from rtemstoolkit import error
+from rtemstoolkit import log
 
 windows = os.name == 'nt'
Index: rtemstoolkit/rtems.py
===================================================================
--- rtemstoolkit/rtems.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/rtems.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -72,5 +72,8 @@
     '''
     if prog is None:
-        exec_name = sys.argv[1]
+        if len(sys.argv) == 1:
+            exec_name = sys.argv[0]
+        else:
+            exec_name = sys.argv[1]
     else:
         exec_name = prog
Index: rtemstoolkit/solaris.py
===================================================================
--- rtemstoolkit/solaris.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/solaris.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -25,12 +25,7 @@
 import os
 
-try:
-    from . import check
-    from . import error
-    from . import execute
-except (ValueError, SystemError):
-    import check
-    import error
-    import execute
+from rtemstoolkit import check
+from rtemstoolkit import error
+from rtemstoolkit import execute
 
 def cpus():
Index: rtemstoolkit/textbox.py
===================================================================
--- rtemstoolkit/textbox.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/textbox.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -40,17 +40,10 @@
 import os
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import error
-except (ValueError, SystemError):
-    import error
+from rtemstoolkit import error
 
 def line(cols, line = '-', marker = '|', indent = 0, linesep = os.linesep):
     s = ' ' * indent + marker
     for c in cols:
-        s += line[0] * (c - 1) + marker
+        s += line[0] * int((c - 1)) + marker
     return s + linesep
 
@@ -65,5 +58,5 @@
         else:
             m = '|'
-        s += '%-*s%s' % (cols[c] - 1, str(data[c]), m)
+        s += '%-*s%s' % (int(cols[c] - 1), str(data[c]), m)
     return s + linesep
 
@@ -71,5 +64,5 @@
     per_col = width / cols
     columns = [per_col for c in range(0, cols)]
-    for remainder in range(0, width - (per_col * cols)):
+    for remainder in range(0, int(width - (per_col * cols))):
         if remainder % 2 == 0:
             columns[remainder] += 1
Index: rtemstoolkit/version.py
===================================================================
--- rtemstoolkit/version.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/version.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -89,17 +89,8 @@
     import ConfigParser as configparser
 
-#
-# Support to handle importing when installed in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import error
-    from . import git
-    from . import rtems
-except (ValueError, SystemError):
-    import error
-    import git
-    import path
-    import rtems
+from rtemstoolkit import error
+from rtemstoolkit import git
+from rtemstoolkit import path
+from rtemstoolkit import rtems
 
 #
Index: rtemstoolkit/windows.py
===================================================================
--- rtemstoolkit/windows.py	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ rtemstoolkit/windows.py	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -35,14 +35,6 @@
 import os
 
-#
-# Support to handle use in a package and as a unit test.
-# If there is a better way to let us know.
-#
-try:
-    from . import error
-    from . import execute
-except (ValueError, SystemError):
-    import error
-    import execute
+from rtemstoolkit import error
+from rtemstoolkit import execute
 
 def cpus():
Index: wscript
===================================================================
--- wscript	(revision 6fa09650b8a936782aa9352e5e23001360317b9d)
+++ wscript	(revision 7e5cdeaabeaa95b8533af626b99a43c93e5ecf6f)
@@ -96,4 +96,9 @@
     ctx.check_python_version((2,6,6))
     #
+    # Find which versions of python are installed for testing.
+    #
+    ctx.find_program('python2', mandatory = False)
+    ctx.find_program('python3', mandatory = False)
+    #
     # Installing the PYO,PYC seems broken on 1.8.19. The path is wrong.
     #
@@ -106,4 +111,6 @@
         ctx.install_files('${PREFIX}/share/rtems/rtemstoolkit', ['VERSION'])
     recurse(ctx)
+    if ctx.cmd == 'test':
+        rtemstoolkit_tests(ctx)
 
 def install(ctx):
@@ -128,8 +135,49 @@
 
 #
-# The doxy command.
+# Custom commands
 #
-from waflib import Build
-class doxy(Build.BuildContext):
+import waflib
+
+class test(waflib.Build.BuildContext):
+    fun = 'build'
+    cmd = 'test'
+
+class doxy(waflib.Build.BuildContext):
     fun = 'build'
     cmd = 'doxy'
+
+#
+# RTEMS Toolkit Tests.
+#
+# Run the tests from the top directory so they are run as python modules.
+#
+def rtemstoolkit_tests(ctx):
+    log = ctx.path.find_or_declare('tests.log')
+    ctx.logger = waflib.Logs.make_logger(log.abspath(), 'build')
+    failures = False
+    for py in ['2', '3']:
+        PY = 'PYTHON%s' % (py)
+        if PY in ctx.env:
+            from rtemstoolkit import all as toolkit_tests
+            from rtemstoolkit import args as toolkit_test_args
+            for tt in toolkit_tests:
+                test = 'rtemstoolkit.%s' % (tt)
+                ctx.start_msg('Test python%s %s' % (py, test))
+                cmd = '%s -m %s' % (ctx.env[PY][0], test)
+                if tt in toolkit_test_args:
+                    cmd += ' ' + ' '.join(toolkit_test_args[tt])
+                ctx.to_log('test command: ' + cmd)
+                try:
+                    (out, err) = ctx.cmd_and_log(cmd,
+                                                 output = waflib.Context.BOTH,
+                                                 quiet = waflib.Context.BOTH)
+                    ctx.to_log(out)
+                    ctx.to_log(err)
+                    ctx.end_msg('pass')
+                except waflib.Errors.WafError as e:
+                    failures = True
+                    ctx.to_log(e.stdout)
+                    ctx.to_log(e.stderr)
+                    ctx.end_msg('fail', color = 'RED')
+    if failures:
+        ctx.fatal('Test failures')
