Skip to content
Snippets Groups Projects
tester.py 4.18 KiB
Newer Older
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Script to start tests and to manage their results
'''
import os
import sys

import utils
from utils import log


class Tester():
    USAGE = '''%s [-e] [-d] [-h]
    -e: send email with report.
    -d: debug mode (can be started with non root users).
    -h: show this message.''' % __file__

    def __init__(self, *args):
        log('\033[96m-------------------------------\033[0m')
        log('\033[96m- UbiCast applications tester -\033[0m')
        log('\033[96m-------------------------------\033[0m')
        args = list(args)
        # Check if help is required
        if '-h' in args:
            log('USAGE: ' + self.USAGE)
            sys.exit(0)
        # Check current dir
        root_dir = utils.get_dir(__file__)
        if root_dir != '':
            os.chdir(root_dir)
        self.root_dir = root_dir
        # Add to python path
        if root_dir not in sys.path:
            sys.path.append(root_dir)
        # Check that this script is run by root
        debug = '-d' in args
        if debug:
            args.remove('-d')
        code, out = utils.exec_cmd(['whoami'], get_out=True)
        if out != 'root' and not debug:
            log('This script should be run as root user.')
            sys.exit(1)
        # Load conf
        conf = utils.load_conf()
        if not conf:
            log('No configuration loaded.')
            sys.exit(1)
        # Check for email value
        email = '-e' in args
        if email:
            args.remove('-i')
        exit_code = self.run_tests(email)
        sys.exit(exit_code)

    def get_file_description(self, path):
        with open(path, 'r') as fo:
            content = fo.read()
        description = ''
        if path.endswith('.py'):
            start = content.find('\'\'\'')
            if start > 0:
                start += 3
                end = content.find('\'\'\'', start)
                if end > 0:
                    description = content[start:end].strip()
        else:
            for line in content.split('\n'):
                if line.startswith('#!'):
                    continue
                elif line.startswith('#'):
                    description += line + '\n'
                else:
                    break
        return description.strip()

    def run_tests(self, email=False):
        path = os.path.join(self.root_dir, 'tests')
        if not os.path.isdir(path):
            log('The tests dir is missing ("%s").' % path)
            return 1
        os.chdir(path)
        names = os.listdir(path)
        names.sort()
        if not names:
            log('The tests dir is empty ("%s").' % path)
            return 1
        results = list()
        exit_code = 0
        # Run all tests
        for name in names:
            log('\033[1;95m-- Test "%s" --\033[0;0m' % name)
            test_path = os.path.join(path, name)
            # Get test description
            description = self.get_file_description(test_path)
            # Run test
            try:
                code = utils.exec_cmd(test_path)
                if code != 0:
                    raise Exception('Command exited with code %s.' % code)
            except Exception as e:
                exit_code = 1
                log(e)
                results.append((False, test_path, description))
            else:
                results.append((True, test_path, description))
        log('\nTests results:')
        html_report = '<table>'
        html_report += '\n<tr><th>Test</th><th>Result</th><th>Description</th></tr>'
        for success, test_path, description in results:
            file_name = os.path.basename(test_path)
            if success:
                html_result = '<span style="color: green;">success</span>'
                term_result = '\033[92msuccess\033[0m'
            else:
                html_result = '<span style="color: red;">failure</span>'
                term_result = '\033[91mfailure\033[0m'
            log('  %s: %s' % (file_name, term_result))
            html_report += '\n<tr><td>%s</td><td>%s</td><td>%s</td></tr>' % (file_name, html_result, description)
        html_report += '\n</table>'
        return exit_code


if __name__ == '__main__':
    Tester(*sys.argv[1:])