diff options
author | Rodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com> | 2017-11-08 12:41:36 +0000 |
---|---|---|
committer | Rodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com> | 2017-12-22 11:40:01 +0000 |
commit | 090b1a166bd19bdb98b0311d58b85582bd1676ed (patch) | |
tree | 74e9c509a9b5e58d8e69773f31dca85b78e13216 /tests/unit/common/test_process.py | |
parent | 9bef739e89f3b230c9e0a53c2286a440017ec948 (diff) |
Replace subprocess "check_output" with "Popen"
"check_output" is a blocking wrapper for "Popen" which returns the output
of the command execution or raises an exception in case of error.
"Popen" is a non-blocking function that allows to create asynchronous
tasks. It returns any possible execution error but doesn't raise an
exception; this is delegated to the developer.
This code is used in the Yardstick CLI base test class.
Change-Id: Ie3e1228b2d40cb306354447653678bf581bc9697
Signed-off-by: Rodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>
Diffstat (limited to 'tests/unit/common/test_process.py')
-rw-r--r-- | tests/unit/common/test_process.py | 106 |
1 files changed, 105 insertions, 1 deletions
diff --git a/tests/unit/common/test_process.py b/tests/unit/common/test_process.py index 5eee55bcc..1c6dfec27 100644 --- a/tests/unit/common/test_process.py +++ b/tests/unit/common/test_process.py @@ -11,10 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -import unittest import mock +import unittest + +from oslo_utils import encodeutils +from yardstick.common import exceptions from yardstick.common import process @@ -44,3 +47,104 @@ class TerminateChildrenTestcase(unittest.TestCase): def test_no_children(self, mock_multiprocessing): mock_multiprocessing.active_children.return_value = [] process.terminate_children() + + +class ExecuteTestCase(unittest.TestCase): + + RET_CODE_OK = 0 + RET_CODE_WRONG = 1 + + def setUp(self): + self._mock_create_process = mock.patch.object(process, + 'create_process') + self.mock_create_process = self._mock_create_process.start() + self.obj = mock.Mock() + self.cmd = mock.Mock() + self.obj.communicate = mock.Mock() + self.stdout = 'std out' + self.stderr = 'std err' + self.obj.communicate.return_value = (self.stdout, self.stderr) + self.mock_create_process.return_value = (self.obj, self.cmd) + self.input_cmd = 'input cmd' + self.additional_env = mock.Mock() + + def test_execute_with_input(self): + process_input = 'process input' + self.obj.returncode = self.RET_CODE_OK + out = process.execute(self.input_cmd, process_input=process_input, + additional_env=self.additional_env) + self.obj.communicate.assert_called_once_with( + encodeutils.to_utf8(process_input)) + self.mock_create_process.assert_called_once_with( + self.input_cmd, run_as_root=False, + additional_env=self.additional_env) + self.assertEqual(self.stdout, out) + + def test_execute_no_input(self): + self.obj.returncode = self.RET_CODE_OK + out = process.execute(self.input_cmd, + additional_env=self.additional_env) + self.obj.communicate.assert_called_once_with(None) + self.mock_create_process.assert_called_once_with( + self.input_cmd, run_as_root=False, + additional_env=self.additional_env) + self.assertEqual(self.stdout, out) + + def test_execute_exception(self): + self.obj.returncode = self.RET_CODE_WRONG + self.assertRaises(exceptions.ProcessExecutionError, process.execute, + self.input_cmd, additional_env=self.additional_env) + self.obj.communicate.assert_called_once_with(None) + + def test_execute_with_extra_code(self): + self.obj.returncode = self.RET_CODE_WRONG + out = process.execute(self.input_cmd, + additional_env=self.additional_env, + extra_ok_codes=[self.RET_CODE_WRONG]) + self.obj.communicate.assert_called_once_with(None) + self.mock_create_process.assert_called_once_with( + self.input_cmd, run_as_root=False, + additional_env=self.additional_env) + self.assertEqual(self.stdout, out) + + def test_execute_exception_no_check(self): + self.obj.returncode = self.RET_CODE_WRONG + out = process.execute(self.input_cmd, + additional_env=self.additional_env, + check_exit_code=False) + self.obj.communicate.assert_called_once_with(None) + self.mock_create_process.assert_called_once_with( + self.input_cmd, run_as_root=False, + additional_env=self.additional_env) + self.assertEqual(self.stdout, out) + + +class CreateProcessTestCase(unittest.TestCase): + + @mock.patch.object(process, 'subprocess_popen') + def test_process_string_command(self, mock_subprocess_popen): + cmd = 'command' + obj = mock.Mock() + mock_subprocess_popen.return_value = obj + out1, out2 = process.create_process(cmd) + self.assertEqual(obj, out1) + self.assertEqual([cmd], out2) + + @mock.patch.object(process, 'subprocess_popen') + def test_process_list_command(self, mock_subprocess_popen): + cmd = ['command'] + obj = mock.Mock() + mock_subprocess_popen.return_value = obj + out1, out2 = process.create_process(cmd) + self.assertEqual(obj, out1) + self.assertEqual(cmd, out2) + + @mock.patch.object(process, 'subprocess_popen') + def test_process_with_env(self, mock_subprocess_popen): + cmd = ['command'] + obj = mock.Mock() + additional_env = {'var1': 'value1'} + mock_subprocess_popen.return_value = obj + out1, out2 = process.create_process(cmd, additional_env=additional_env) + self.assertEqual(obj, out1) + self.assertEqual(['env', 'var1=value1'] + cmd, out2) |