3 # Copyright (c) 2017 Orange and others.
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
10 # pylint: disable=missing-docstring
19 from xtesting.core import feature
20 from xtesting.core import testcase
23 class FakeTestCase(feature.Feature):
25 def execute(self, **kwargs):
29 class AbstractFeatureTesting(unittest.TestCase):
31 def test_run_unimplemented(self):
32 # pylint: disable=abstract-class-instantiated
33 with self.assertRaises(TypeError):
34 feature.Feature(case_name="feature", project_name="xtesting")
37 class FeatureTestingBase(unittest.TestCase):
41 _repo = "dir_repo_bar"
42 _cmd = "run_bar_tests.py"
43 _output_file = '/var/lib/xtesting/results/foo/foo.log'
46 @mock.patch('time.time', side_effect=[1, 2])
47 def _test_run(self, status, mock_method=None):
48 self.assertEqual(self.feature.run(cmd=self._cmd), status)
49 if status == testcase.TestCase.EX_OK:
50 self.assertEqual(self.feature.result, 100)
52 self.assertEqual(self.feature.result, 0)
53 mock_method.assert_has_calls([mock.call(), mock.call()])
54 self.assertEqual(self.feature.start_time, 1)
55 self.assertEqual(self.feature.stop_time, 2)
57 @mock.patch('time.time', side_effect=[1, 2])
58 def _test_run_console(self, console, status, mock_method=None):
60 self.feature.run(cmd=self._cmd, console=console), status)
61 self.assertEqual(self.feature.result, 100)
62 mock_method.assert_has_calls([mock.call(), mock.call()])
63 self.assertEqual(self.feature.start_time, 1)
64 self.assertEqual(self.feature.stop_time, 2)
67 class FeatureTesting(FeatureTestingBase):
70 # logging must be disabled else it calls time.time()
71 # what will break these unit tests.
72 logging.disable(logging.CRITICAL)
73 with mock.patch('six.moves.builtins.open'):
74 self.feature = FakeTestCase(
75 project_name=self._project_name, case_name=self._case_name)
77 def test_run_exc(self):
78 # pylint: disable=bad-continuation
79 with mock.patch.object(
80 self.feature, 'execute',
81 side_effect=Exception) as mock_method:
82 self._test_run(testcase.TestCase.EX_RUN_ERROR)
83 mock_method.assert_called_once_with(cmd=self._cmd)
86 self._test_run(testcase.TestCase.EX_RUN_ERROR)
89 class BashFeatureTesting(FeatureTestingBase):
92 # logging must be disabled else it calls time.time()
93 # what will break these unit tests.
94 logging.disable(logging.CRITICAL)
95 with mock.patch('six.moves.builtins.open'):
96 self.feature = feature.BashFeature(
97 project_name=self._project_name, case_name=self._case_name)
99 @mock.patch('subprocess.Popen')
100 def test_run_no_cmd(self, mock_subproc):
102 self.feature.run(), testcase.TestCase.EX_RUN_ERROR)
103 mock_subproc.assert_not_called()
105 @mock.patch('os.path.isdir', return_value=True)
106 @mock.patch('subprocess.Popen',
107 side_effect=subprocess.CalledProcessError(0, '', ''))
108 def test_run_ko1(self, *args):
109 with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
110 self._test_run(testcase.TestCase.EX_RUN_ERROR)
111 mopen.assert_called_once_with(self._output_file, "w")
112 args[0].assert_called_once_with(
113 self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
114 args[1].assert_called_once_with(self.feature.res_dir)
116 @mock.patch('os.path.isdir', return_value=True)
117 @mock.patch('subprocess.Popen')
118 def test_run_ko2(self, *args):
119 stream = six.BytesIO()
122 attrs = {'return_value.stdout': stream, 'return_value.returncode': 1}
123 args[0].configure_mock(**attrs)
124 with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
125 self._test_run(testcase.TestCase.EX_RUN_ERROR)
126 self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
127 self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
128 args[0].assert_called_once_with(
129 self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
130 args[1].assert_called_once_with(self.feature.res_dir)
132 @mock.patch('os.path.isdir', return_value=True)
133 @mock.patch('subprocess.Popen')
134 def test_run1(self, *args):
135 stream = six.BytesIO()
138 attrs = {'return_value.stdout': stream, 'return_value.returncode': 0}
139 args[0].configure_mock(**attrs)
140 with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
141 self._test_run(testcase.TestCase.EX_OK)
142 self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
143 self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
144 args[0].assert_called_once_with(
145 self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
146 args[1].assert_called_once_with(self.feature.res_dir)
148 @mock.patch('os.path.isdir', return_value=True)
149 @mock.patch('subprocess.Popen')
150 def test_run2(self, *args):
151 stream = six.BytesIO()
154 attrs = {'return_value.stdout': stream, 'return_value.returncode': 0}
155 args[0].configure_mock(**attrs)
156 with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
157 self._test_run_console(True, testcase.TestCase.EX_OK)
158 self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
159 self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
160 args[0].assert_called_once_with(
161 self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
162 args[1].assert_called_once_with(self.feature.res_dir)
164 @mock.patch('os.path.isdir', return_value=True)
165 @mock.patch('subprocess.Popen')
166 def test_run3(self, *args):
167 stream = six.BytesIO()
170 attrs = {'return_value.stdout': stream, 'return_value.returncode': 0}
171 args[0].configure_mock(**attrs)
172 with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
173 self._test_run_console(False, testcase.TestCase.EX_OK)
174 self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
175 self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
176 args[0].assert_called_once_with(
177 self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
178 args[1].assert_called_once_with(self.feature.res_dir)
180 @mock.patch('os.makedirs')
181 @mock.patch('os.path.isdir', return_value=False)
182 @mock.patch('subprocess.Popen')
183 def test_run4(self, *args):
184 stream = six.BytesIO()
187 attrs = {'return_value.stdout': stream, 'return_value.returncode': 0}
188 args[0].configure_mock(**attrs)
189 with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
190 self._test_run_console(False, testcase.TestCase.EX_OK)
191 self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
192 self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
193 args[0].assert_called_once_with(
194 self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
195 args[1].assert_called_once_with(self.feature.res_dir)
196 args[2].assert_called_once_with(self.feature.res_dir)
199 if __name__ == "__main__":
200 unittest.main(verbosity=2)