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
21 from xtesting.core import feature
22 from xtesting.core import testcase
23 from xtesting.utils import constants
26 class FakeTestCase(feature.Feature):
28 def execute(self, **kwargs):
32 class AbstractFeatureTesting(unittest.TestCase):
34 def test_run_unimplemented(self):
35 # pylint: disable=abstract-class-instantiated
36 with self.assertRaises(TypeError):
37 feature.Feature(case_name="feature", project_name="xtesting")
40 class FeatureTestingBase(unittest.TestCase):
44 _repo = "dir_repo_bar"
45 _cmd = "run_bar_tests.py"
46 _output_file = os.path.join(constants.RESULTS_DIR, 'foo/foo.log')
49 @mock.patch('time.time', side_effect=[1, 2])
50 def _test_run(self, status, mock_method=None):
51 self.assertEqual(self.feature.run(cmd=self._cmd), status)
52 if status == testcase.TestCase.EX_OK:
53 self.assertEqual(self.feature.result, 100)
55 self.assertEqual(self.feature.result, 0)
56 mock_method.assert_has_calls([mock.call(), mock.call()])
57 self.assertEqual(self.feature.start_time, 1)
58 self.assertEqual(self.feature.stop_time, 2)
60 @mock.patch('time.time', side_effect=[1, 2])
61 def _test_run_console(self, console, status, mock_method=None):
63 self.feature.run(cmd=self._cmd, console=console), status)
64 self.assertEqual(self.feature.result, 100)
65 mock_method.assert_has_calls([mock.call(), mock.call()])
66 self.assertEqual(self.feature.start_time, 1)
67 self.assertEqual(self.feature.stop_time, 2)
70 class FeatureTesting(FeatureTestingBase):
73 # logging must be disabled else it calls time.time()
74 # what will break these unit tests.
75 logging.disable(logging.CRITICAL)
76 with mock.patch('six.moves.builtins.open'):
77 self.feature = FakeTestCase(
78 project_name=self._project_name, case_name=self._case_name)
80 def test_run_exc(self):
81 # pylint: disable=bad-continuation
82 with mock.patch.object(
83 self.feature, 'execute',
84 side_effect=Exception) as mock_method:
85 self._test_run(testcase.TestCase.EX_RUN_ERROR)
86 mock_method.assert_called_once_with(cmd=self._cmd)
89 self._test_run(testcase.TestCase.EX_RUN_ERROR)
92 class BashFeatureTesting(FeatureTestingBase):
95 # logging must be disabled else it calls time.time()
96 # what will break these unit tests.
97 logging.disable(logging.CRITICAL)
98 with mock.patch('six.moves.builtins.open'):
99 self.feature = feature.BashFeature(
100 project_name=self._project_name, case_name=self._case_name)
102 @mock.patch('subprocess.Popen')
103 def test_run_no_cmd(self, mock_subproc):
105 self.feature.run(), testcase.TestCase.EX_RUN_ERROR)
106 mock_subproc.assert_not_called()
108 @mock.patch('os.path.isdir', return_value=True)
109 @mock.patch('subprocess.Popen',
110 side_effect=subprocess.CalledProcessError(0, '', ''))
111 def test_run_ko1(self, *args):
112 with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
113 self._test_run(testcase.TestCase.EX_RUN_ERROR)
114 mopen.assert_called_once_with(self._output_file, "w")
115 args[0].assert_called_once_with(
116 self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
117 args[1].assert_called_once_with(self.feature.res_dir)
119 @mock.patch('os.path.isdir', return_value=True)
120 @mock.patch('subprocess.Popen')
121 def test_run_ko2(self, *args):
122 stream = six.BytesIO()
125 attrs = {'return_value.stdout': stream, 'return_value.returncode': 1}
126 args[0].configure_mock(**attrs)
127 with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
128 self._test_run(testcase.TestCase.EX_RUN_ERROR)
129 self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
130 self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
131 args[0].assert_called_once_with(
132 self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
133 args[1].assert_called_once_with(self.feature.res_dir)
135 @mock.patch('os.path.isdir', return_value=True)
136 @mock.patch('subprocess.Popen')
137 def test_run1(self, *args):
138 stream = six.BytesIO()
141 attrs = {'return_value.stdout': stream, 'return_value.returncode': 0}
142 args[0].configure_mock(**attrs)
143 with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
144 self._test_run(testcase.TestCase.EX_OK)
145 self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
146 self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
147 args[0].assert_called_once_with(
148 self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
149 args[1].assert_called_once_with(self.feature.res_dir)
151 @mock.patch('os.path.isdir', return_value=True)
152 @mock.patch('subprocess.Popen')
153 def test_run2(self, *args):
154 stream = six.BytesIO()
157 attrs = {'return_value.stdout': stream, 'return_value.returncode': 0}
158 args[0].configure_mock(**attrs)
159 with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
160 self._test_run_console(True, testcase.TestCase.EX_OK)
161 self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
162 self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
163 args[0].assert_called_once_with(
164 self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
165 args[1].assert_called_once_with(self.feature.res_dir)
167 @mock.patch('os.path.isdir', return_value=True)
168 @mock.patch('subprocess.Popen')
169 def test_run3(self, *args):
170 stream = six.BytesIO()
173 attrs = {'return_value.stdout': stream, 'return_value.returncode': 0}
174 args[0].configure_mock(**attrs)
175 with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
176 self._test_run_console(False, testcase.TestCase.EX_OK)
177 self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
178 self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
179 args[0].assert_called_once_with(
180 self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
181 args[1].assert_called_once_with(self.feature.res_dir)
183 @mock.patch('os.makedirs')
184 @mock.patch('os.path.isdir', return_value=False)
185 @mock.patch('subprocess.Popen')
186 def test_run4(self, *args):
187 stream = six.BytesIO()
190 attrs = {'return_value.stdout': stream, 'return_value.returncode': 0}
191 args[0].configure_mock(**attrs)
192 with mock.patch('six.moves.builtins.open', mock.mock_open()) as mopen:
193 self._test_run_console(False, testcase.TestCase.EX_OK)
194 self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
195 self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
196 args[0].assert_called_once_with(
197 self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
198 args[1].assert_called_once_with(self.feature.res_dir)
199 args[2].assert_called_once_with(self.feature.res_dir)
202 if __name__ == "__main__":
203 unittest.main(verbosity=2)