summaryrefslogtreecommitdiff
path: root/test/test_scripts.py
blob: 74ae7148998870a19f54b618811fc49d18a3cff9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env python
# coding: utf-8

"""
This module tests that the scripts are all callable.
"""

from __future__ import absolute_import

import subprocess
import unittest
import sys
import errno
from abc import ABCMeta, abstractmethod

from .config import *


class CanScriptTest(unittest.TestCase):

    __metaclass__ = ABCMeta

    @classmethod
    def setUpClass(cls):
        # clean up the argument list so the call to the main() functions
        # in test_does_not_crash() succeeds
        sys.argv = sys.argv[:1]

    def test_do_commands_exist(self):
        """This test calls each scripts once and verifies that the help
        can be read without any other errors, like the script not being
        found.
        """
        for command in self._commands():
            try:
                subprocess.check_output(command.split(), stderr=subprocess.STDOUT)
            except subprocess.CalledProcessError as e:
                return_code = e.returncode
                output = e.output
            else:
                return_code = 0
                output = "-- NO OUTPUT --"

            allowed = [0, errno.EINVAL]
            self.assertIn(return_code, allowed,
                    'Calling "{}" failed (exit code was {} and not SUCCESS/0 or EINVAL/22):\n{}'
                    .format(command, return_code, output))

    def test_does_not_crash(self):
        # test import
        module = self._import()
        # test main method
        with self.assertRaises(SystemExit) as cm:
            module.main()
        self.assertEqual(cm.exception.code, errno.EINVAL)

    @abstractmethod
    def _commands(self):
        """Returns an Iterable of commands that should "succeed", meaning they exit
        normally (exit code 0) or with the exit code for invalid arguments: EINVAL/22.
        """
        pass

    @abstractmethod
    def _import(self):
        """Returns the modue of the script that has a main() function.
        """
        pass


class TestLoggerScript(CanScriptTest):

    def _commands(self):
        commands = [
            "python -m can.logger --help",
            "python scripts/can_logger.py --help"
        ]
        if IS_UNIX:
            commands += ["can_logger.py --help"]
        return commands

    def _import(self):
        import can.logger as module
        return module


class TestPlayerScript(CanScriptTest):

    def _commands(self):
        commands = [
            "python -m can.player --help",
            "python scripts/can_player.py --help"
        ]
        if IS_UNIX:
            commands += ["can_player.py --help"]
        return commands

    def _import(self):
        import can.player as module
        return module


# TODO add #390


# this excludes the base class from being executed as a test case itself
del(CanScriptTest)


if __name__ == '__main__':
    unittest.main()