Set shell=True in subprocess.check_call
[functest-xtesting.git] / xtesting / tests / unit / core / test_feature.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2017 Orange and others.
4 #
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9
10 # pylint: disable=missing-docstring
11
12 import logging
13 import subprocess
14 import unittest
15
16 import mock
17
18 from xtesting.core import feature
19 from xtesting.core import testcase
20
21
22 class FakeTestCase(feature.Feature):
23
24     def execute(self, **kwargs):
25         pass
26
27
28 class AbstractFeatureTesting(unittest.TestCase):
29
30     def test_run_unimplemented(self):
31         with self.assertRaises(TypeError):
32             feature.Feature(case_name="feature", project_name="xtesting")
33
34
35 class FeatureTestingBase(unittest.TestCase):
36
37     _case_name = "foo"
38     _project_name = "bar"
39     _repo = "dir_repo_bar"
40     _cmd = "run_bar_tests.py"
41     _output_file = '/var/lib/xtesting/results/foo.log'
42     feature = None
43
44     @mock.patch('time.time', side_effect=[1, 2])
45     def _test_run(self, status, mock_method=None):
46         self.assertEqual(self.feature.run(cmd=self._cmd), status)
47         if status == testcase.TestCase.EX_OK:
48             self.assertEqual(self.feature.result, 100)
49         else:
50             self.assertEqual(self.feature.result, 0)
51         mock_method.assert_has_calls([mock.call(), mock.call()])
52         self.assertEqual(self.feature.start_time, 1)
53         self.assertEqual(self.feature.stop_time, 2)
54
55
56 class FeatureTesting(FeatureTestingBase):
57
58     def setUp(self):
59         # logging must be disabled else it calls time.time()
60         # what will break these unit tests.
61         logging.disable(logging.CRITICAL)
62         with mock.patch('six.moves.builtins.open'):
63             self.feature = FakeTestCase(
64                 project_name=self._project_name, case_name=self._case_name)
65
66     def test_run_exc(self):
67         # pylint: disable=bad-continuation
68         with mock.patch.object(
69                 self.feature, 'execute',
70                 side_effect=Exception) as mock_method:
71             self._test_run(testcase.TestCase.EX_RUN_ERROR)
72             mock_method.assert_called_once_with(cmd=self._cmd)
73
74     def test_run(self):
75         self._test_run(testcase.TestCase.EX_RUN_ERROR)
76
77
78 class BashFeatureTesting(FeatureTestingBase):
79
80     def setUp(self):
81         # logging must be disabled else it calls time.time()
82         # what will break these unit tests.
83         logging.disable(logging.CRITICAL)
84         with mock.patch('six.moves.builtins.open'):
85             self.feature = feature.BashFeature(
86                 project_name=self._project_name, case_name=self._case_name)
87
88     @mock.patch('subprocess.check_call')
89     def test_run_no_cmd(self, mock_subproc):
90         delattr(FeatureTesting, "_cmd")
91         self.assertEqual(
92             self.feature.run(), testcase.TestCase.EX_RUN_ERROR)
93         mock_subproc.assert_not_called()
94
95     @mock.patch('subprocess.check_call',
96                 side_effect=subprocess.CalledProcessError(0, '', ''))
97     def test_run_ko(self, mock_subproc):
98         setattr(FeatureTesting, "_cmd", "run_bar_tests.py")
99         with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
100             self._test_run(testcase.TestCase.EX_RUN_ERROR)
101         mopen.assert_called_once_with(self._output_file, "w+")
102         mock_subproc.assert_called_once_with(
103             self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
104
105     @mock.patch('subprocess.check_call')
106     def test_run(self, mock_subproc):
107         setattr(FeatureTesting, "_cmd", "run_bar_tests.py")
108         with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
109             self._test_run(testcase.TestCase.EX_OK)
110         mopen.assert_called_once_with(self._output_file, "w+")
111         mock_subproc.assert_called_once_with(
112             self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
113
114
115 if __name__ == "__main__":
116     unittest.main(verbosity=2)