def test_001_check_call(self, execute, logger): exit_code = 0 return_value = exec_helpers.ExecResult( cmd=command, stdout=stdout_list, stderr=stdout_list, exit_code=exit_code, ) execute.return_value = return_value verbose = False runner = exec_helpers.Subprocess() # noinspection PyTypeChecker result = runner.check_call( command=command, verbose=verbose, timeout=None) execute.assert_called_once_with(command, verbose, None) self.assertEqual(result, return_value) exit_code = 1 return_value = exec_helpers.ExecResult( cmd=command, stdout=stdout_list, stderr=stdout_list, exit_code=exit_code, ) execute.reset_mock() execute.return_value = return_value with self.assertRaises(exec_helpers.CalledProcessError): # noinspection PyTypeChecker runner.check_call(command=command, verbose=verbose, timeout=None) execute.assert_called_once_with(command, verbose, None)
def test_stdout_lxml(self): """Test lxml etree decode.""" result = exec_helpers.ExecResult( "test", stdout=[b"<?xml version='1.0'?>\n", b"<data>123</data>\n"]) expect = lxml.etree.fromstring( b"<?xml version='1.0'?>\n<data>123</data>\n") self.assertEqual(lxml.etree.tostring(expect), lxml.etree.tostring(result.stdout_lxml))
def exec_result(run_parameters): return exec_helpers.ExecResult( cmd=command, stdin=run_parameters["stdin"], stdout=tuple([line for line in run_parameters["stdout"]]) if run_parameters["stdout"] else None, stderr=tuple([line for line in run_parameters["stderr"]]) if run_parameters["stderr"] else None, exit_code=run_parameters["ec"], )
def test_003_check_stderr(self, check_call, _, logger): return_value = exec_helpers.ExecResult( cmd=command, stdout=stdout_list, exit_code=0, ) check_call.return_value = return_value verbose = False raise_on_err = True runner = exec_helpers.Subprocess() # noinspection PyTypeChecker result = runner.check_stderr(command=command, verbose=verbose, timeout=None, raise_on_err=raise_on_err) check_call.assert_called_once_with(command, verbose, timeout=None, error_info=None, raise_on_err=raise_on_err) self.assertEqual(result, return_value) return_value = exec_helpers.ExecResult( cmd=command, stdout=stdout_list, stderr=stdout_list, exit_code=0, ) check_call.reset_mock() check_call.return_value = return_value with self.assertRaises(exec_helpers.CalledProcessError): # noinspection PyTypeChecker runner.check_stderr(command=command, verbose=verbose, timeout=None, raise_on_err=raise_on_err) check_call.assert_called_once_with(command, verbose, timeout=None, error_info=None, raise_on_err=raise_on_err)
def test_wrong_result(self, logger): """Test logging exception if stdout if not a correct json.""" cmd = r"ls -la | awk '{print $1\}'" result = exec_helpers.ExecResult(cmd=cmd) with self.assertRaises(exec_helpers.ExecHelperError): # noinspection PyStatementEffect result.stdout_json # pylint: disable=pointless-statement logger.assert_has_calls((mock.call.exception( f"{cmd} stdout is not valid json:\n{result.stdout_str!r}\n"), ))
def test_not_implemented(self, logger): """Test assertion on non implemented deserializer""" result = exec_helpers.ExecResult(cmd=cmd) deserialize = getattr(result, '_ExecResult__deserialize') with self.assertRaises(NotImplementedError): deserialize('tst') logger.assert_has_calls((mock.call.error( '{fmt} deserialize target is not implemented'.format( fmt='tst')), ))
def test_setters(self): result = exec_helpers.ExecResult(cmd=cmd) self.assertEqual(result.exit_code, exec_helpers.ExitCodes.EX_INVALID) tst_stdout = [ b'Test\n', b'long\n', b'stdout\n', b'data\n', b' \n', b'5\n', b'6\n', b'7\n', b'8\n', b'end!\n' ] tst_stderr = [b'test\n'] * 10 with mock.patch('exec_helpers.exec_result.logger', autospec=True): result.read_stdout(tst_stdout) self.assertEqual(result.stdout, tuple(tst_stdout)) self.assertEqual(result.stdout, result['stdout']) with mock.patch('exec_helpers.exec_result.logger', autospec=True): result.read_stderr(tst_stderr) self.assertEqual(result.stderr, tuple(tst_stderr)) self.assertEqual(result.stderr, result['stderr']) with self.assertRaises(TypeError): result.exit_code = 'code' result.exit_code = 0 self.assertEqual(result.exit_code, 0) self.assertEqual(result.exit_code, result['exit_code']) with self.assertRaises(RuntimeError): result.exit_code = 1 self.assertEqual(result.exit_code, 0) self.assertEqual(result.stdout_bin, bytearray(b''.join(tst_stdout))) self.assertEqual(result.stderr_bin, bytearray(b''.join(tst_stderr))) stdout_br = tst_stdout[:3] + [b'...\n'] + tst_stdout[-3:] stderr_br = tst_stderr[:3] + [b'...\n'] + tst_stderr[-3:] stdout_brief = b''.join(stdout_br).strip().decode(encoding='utf-8') stderr_brief = b''.join(stderr_br).strip().decode(encoding='utf-8') self.assertEqual(result.stdout_brief, stdout_brief) self.assertEqual(result.stderr_brief, stderr_brief)
def test_finalize(self): """After return code, no stdout/stderr/new code can be received.""" result = exec_helpers.ExecResult(cmd) result.exit_code = 0 with self.assertRaises(RuntimeError): result.exit_code = 1 with self.assertRaises(RuntimeError): result.read_stdout([b"out"]) with self.assertRaises(RuntimeError): result.read_stderr([b"err"])
def test_wrong_result(self, logger): """Test logging exception if stdout if not a correct json""" cmd = "ls -la | awk \'{print $1\}\'" result = exec_helpers.ExecResult(cmd=cmd) with self.assertRaises(exec_helpers.ExecHelperError): # pylint: disable=pointless-statement # noinspection PyStatementEffect result.stdout_json # pylint: enable=pointless-statement logger.assert_has_calls( (mock.call.exception("{cmd} stdout is not valid json:\n" "{stdout_str!r}\n".format(cmd=cmd, stdout_str='')), )) self.assertIsNone(result['stdout_yaml'])
def test_create_minimal(self, logger): """Test defaults.""" result = exec_helpers.ExecResult(cmd=cmd) self.assertEqual(result.cmd, cmd) self.assertEqual(result.cmd, result["cmd"]) self.assertEqual(result.stdout, ()) self.assertEqual(result.stdout, result["stdout"]) self.assertEqual(result.stderr, ()) self.assertEqual(result.stderr, result["stderr"]) self.assertEqual(result.stdout_bin, bytearray()) self.assertEqual(result.stderr_bin, bytearray()) self.assertEqual(result.stdout_str, "") self.assertEqual(result.stdout_str, result["stdout_str"]) self.assertEqual(result.stderr_str, "") self.assertEqual(result.stderr_str, result["stderr_str"]) self.assertEqual(result.stdout_brief, "") self.assertEqual(result.stdout_brief, result["stdout_brief"]) self.assertEqual(result.stderr_brief, "") self.assertEqual(result.stderr_brief, result["stderr_brief"]) self.assertEqual(result.exit_code, exec_helpers.ExitCodes.EX_INVALID) self.assertEqual(result.exit_code, result["exit_code"]) self.assertEqual( repr(result), f"{exec_helpers.ExecResult.__name__}" f"(cmd={cmd!r}, stdout={()}, stderr={()}, exit_code={proc_enums.INVALID!s},)", ) self.assertEqual( str(result), f"""{exec_helpers.ExecResult.__name__}(\n\tcmd={cmd!r},""" f"""\n\tstdout=\n'{""}',""" f"""\n\tstderr=\n'{""}', """ f"\n\texit_code={proc_enums.INVALID!s},\n)", ) with self.assertRaises(IndexError): # noinspection PyStatementEffect result["nonexistent"] # pylint: disable=pointless-statement with self.assertRaises(exec_helpers.ExecHelperError): # noinspection PyStatementEffect result["stdout_json"] # pylint: disable=pointless-statement logger.assert_has_calls((mock.call.exception( f"{cmd} stdout is not valid json:\n{result.stdout_str!r}\n"), )) self.assertEqual( hash(result), hash((exec_helpers.ExecResult, cmd, None, (), (), proc_enums.INVALID)))
def exec_result(run_parameters): command_parameters: CommandParameters = run_parameters["command_parameters"] mock_parameters: MockParameters = run_parameters["mock_parameters"] stdout = run_parameters.get("stdout", None) if stdout is None: stdout_res = None else: stdout_res = tuple([elem for elem in run_parameters["stdout"] if isinstance(elem, bytes)]) return exec_helpers.ExecResult( cmd=run_parameters.get("masked_cmd", command), stdin=command_parameters.stdin, stdout=stdout_res, stderr=(), exit_code=0 if 0 in mock_parameters.ec else exec_helpers.ExitCodes.EX_INVALID, )
def test_started(self): """Test timestamp.""" started = datetime.datetime.utcnow() result = exec_helpers.ExecResult(cmd, exit_code=0, started=started) spent = (result.timestamp - started).seconds self.assertIs(result.started, started) self.assertEqual( str(result), f"""{exec_helpers.ExecResult.__name__}(\n\tcmd={cmd!r},""" f"""\n\tstdout=\n'{""}',""" f"""\n\tstderr=\n'{""}', """ f"""\n\texit_code={proc_enums.EXPECTED!s},""" f"""\n\tstarted={started.strftime("%Y-%m-%d %H:%M:%S")},""" f"\n\tspent={spent // (60 * 60):02d}:{spent // 60:02d}:{spent % 60:02d}," "\n)", )
def test_setters(self): """Test setters: unlocked and final.""" result = exec_helpers.ExecResult(cmd=cmd) self.assertEqual(result.exit_code, exec_helpers.ExitCodes.EX_INVALID) tst_stdout = [ b"Test\n", b"long\n", b"stdout\n", b"data\n", b" \n", b"5\n", b"6\n", b"7\n", b"8\n", b"end!\n" ] tst_stderr = [b"test\n"] * 10 with mock.patch("exec_helpers.exec_result.LOGGER", autospec=True): result.read_stdout(tst_stdout) self.assertEqual(result.stdout, tuple(tst_stdout)) self.assertEqual(result.stdout, result["stdout"]) with mock.patch("exec_helpers.exec_result.LOGGER", autospec=True): result.read_stderr(tst_stderr) self.assertEqual(result.stderr, tuple(tst_stderr)) self.assertEqual(result.stderr, result["stderr"]) with self.assertRaises(TypeError): result.exit_code = "code" result.exit_code = 0 self.assertEqual(result.exit_code, 0) self.assertEqual(result.exit_code, result["exit_code"]) with self.assertRaises(RuntimeError): result.exit_code = 1 self.assertEqual(result.exit_code, 0) self.assertEqual(result.stdout_bin, bytearray(b"".join(tst_stdout))) self.assertEqual(result.stderr_bin, bytearray(b"".join(tst_stderr))) stdout_br = tst_stdout[:3] + [b"...\n"] + tst_stdout[-3:] stderr_br = tst_stderr[:3] + [b"...\n"] + tst_stderr[-3:] stdout_brief = b"".join(stdout_br).strip().decode(encoding="utf-8") stderr_brief = b"".join(stderr_br).strip().decode(encoding="utf-8") self.assertEqual(result.stdout_brief, stdout_brief) self.assertEqual(result.stderr_brief, stderr_brief)
def test_pretty_repr(self): """Test repr with logwrap.""" result = exec_helpers.ExecResult("test", stdout=[b"{test: data}"], stderr=[b"{test: stderr}"]) pretty_repr = logwrap.pretty_repr(result) self.assertEqual( f"ExecResult(\n" f" cmd='test',\n" f" stdout=(\n" f" b'{{test: data}}',\n" f" ),\n" f" stderr=(\n" f" b'{{test: stderr}}',\n" f" ),\n" f" exit_code={result.exit_code!s},\n" f")", pretty_repr, )
def prepare_close( popen, cmd=command, stderr_val=None, ec=0, open_stdout=True, stdout_override=None, open_stderr=True, cmd_in_result=None, ): if open_stdout: stdout_lines = stdout_list if stdout_override is None else stdout_override stdout = FakeFileStream(*stdout_lines) else: stdout = stdout_lines = None if open_stderr: stderr_lines = stderr_list if stderr_val is None else [] stderr = FakeFileStream(*stderr_lines) else: stderr = stderr_lines = None popen_obj = mock.Mock() if stdout: popen_obj.attach_mock(stdout, 'stdout') else: popen_obj.configure_mock(stdout=None) if stderr: popen_obj.attach_mock(stderr, 'stderr') else: popen_obj.configure_mock(stderr=None) popen_obj.configure_mock(returncode=ec) popen.return_value = popen_obj # noinspection PyTypeChecker exp_result = exec_helpers.ExecResult( cmd=cmd_in_result if cmd_in_result is not None else cmd, stderr=stderr_lines, stdout=stdout_lines, exit_code=ec ) return popen_obj, exp_result
def test_indexed_lines_access(self): """Test custom indexes usage for construction string from output.""" result = exec_helpers.ExecResult( cmd, stdout=( b"line0\n", b"line1\n", b"line2\n", b"line3\n", b"line4\n", b"line5\n", b"line6\n", b"line7\n", b"line8\n", b"line9\n", ), stderr=( b"e_line0\n", b"e_line1\n", b"e_line2\n", b"e_line3\n", b"e_line4\n", b"e_line5\n", b"e_line6\n", b"e_line7\n", b"e_line8\n", b"e_line9\n", ), ) self.assertEqual(result.stdout_lines[:], result.stdout_str) self.assertEqual(result.stderr_lines[:], result.stderr_str) self.assertEqual(result.stdout_lines[0], "line0") self.assertEqual(result.stdout_lines[0, 1], "line0\nline1") self.assertEqual(result.stdout_lines[0, 2], "line0\nline2") self.assertEqual(result.stdout_lines[0, ..., 2], "line0\n...\nline2") self.assertEqual(result.stdout_lines[:1, ..., 2], "line0\n...\nline2") with self.assertRaises(TypeError): _ = result.stdout_lines["aaa"] # noqa with self.assertRaises(TypeError): _ = result.stdout_lines[1, "aaa"] # noqa
def test_not_equal(self): """Exec result equality is validated by all fields.""" result1 = exec_helpers.ExecResult("cmd1") result2 = exec_helpers.ExecResult("cmd2") self.assertNotEqual(result1, result2) result1 = exec_helpers.ExecResult(cmd) result2 = exec_helpers.ExecResult(cmd) result1.read_stdout([b"a"]) result2.read_stdout([b"b"]) self.assertNotEqual(result1, result2) result1 = exec_helpers.ExecResult(cmd) result2 = exec_helpers.ExecResult(cmd) result1.read_stderr([b"a"]) result2.read_stderr([b"b"]) self.assertNotEqual(result1, result2) result1 = exec_helpers.ExecResult(cmd) result2 = exec_helpers.ExecResult(cmd) result1.exit_code = 0 result2.exit_code = 1 self.assertNotEqual(result1, result2)
def test_stdin_none(self): """Test with empty STDIN.""" result = exec_helpers.ExecResult(cmd, exit_code=0) self.assertIsNone(result.stdin)
def test_stdout_yaml_ruamel(self): """Test yaml decode with ruamel.yaml.""" result = exec_helpers.ExecResult("test", stdout=[b"{test: data}\n"]) expect = {"test": "data"} result = result.stdout_yaml self.assertEqual(expect, result)
def test_stdin_bytearray(self): result = exec_helpers.ExecResult(cmd, stdin=bytearray(b'STDIN'), exit_code=0) self.assertEqual(result.stdin, u'STDIN')
def test_stdin_bytearray(self): """Test with bytearray STDIN.""" result = exec_helpers.ExecResult(cmd, stdin=bytearray(b"STDIN"), exit_code=0) self.assertEqual(result.stdin, "STDIN")
def test_json(self): result = exec_helpers.ExecResult('test', stdout=[b'{"test": true}']) self.assertEqual(result.stdout_json, {'test': True})
def test_stdin_utf(self): result = exec_helpers.ExecResult(cmd, stdin=u'STDIN', exit_code=0) self.assertEqual(result.stdin, u'STDIN')
def test_create_minimal(self, logger): """Test defaults""" result = exec_helpers.ExecResult(cmd=cmd) self.assertEqual(result.cmd, cmd) self.assertEqual(result.cmd, result['cmd']) self.assertEqual(result.stdout, ()) self.assertEqual(result.stdout, result['stdout']) self.assertEqual(result.stderr, ()) self.assertEqual(result.stderr, result['stderr']) self.assertEqual(result.stdout_bin, bytearray()) self.assertEqual(result.stderr_bin, bytearray()) self.assertEqual(result.stdout_str, '') self.assertEqual(result.stdout_str, result['stdout_str']) self.assertEqual(result.stderr_str, '') self.assertEqual(result.stderr_str, result['stderr_str']) self.assertEqual(result.stdout_brief, '') self.assertEqual(result.stdout_brief, result['stdout_brief']) self.assertEqual(result.stderr_brief, '') self.assertEqual(result.stderr_brief, result['stderr_brief']) self.assertEqual(result.exit_code, exec_helpers.ExitCodes.EX_INVALID) self.assertEqual(result.exit_code, result['exit_code']) self.assertEqual( repr(result), '{cls}(cmd={cmd!r}, stdout={stdout}, stderr={stderr}, ' 'exit_code={exit_code!s})'.format( cls=exec_helpers.ExecResult.__name__, cmd=cmd, stdout=(), stderr=(), exit_code=exec_helpers.ExitCodes.EX_INVALID ) ) self.assertEqual( str(result), "{cls}(\n\tcmd={cmd!r}," "\n\t stdout=\n'{stdout_brief}'," "\n\tstderr=\n'{stderr_brief}', " '\n\texit_code={exit_code!s}\n)'.format( cls=exec_helpers.ExecResult.__name__, cmd=cmd, stdout_brief='', stderr_brief='', exit_code=exec_helpers.ExitCodes.EX_INVALID ) ) with self.assertRaises(IndexError): # pylint: disable=pointless-statement # noinspection PyStatementEffect result['nonexistent'] # pylint: enable=pointless-statement with self.assertRaises(exec_helpers.ExecHelperError): # pylint: disable=pointless-statement # noinspection PyStatementEffect result['stdout_json'] # pylint: enable=pointless-statement logger.assert_has_calls(( mock.call.exception( "{cmd} stdout is not valid json:\n" "{stdout_str!r}\n".format( cmd=cmd, stdout_str='')), )) self.assertIsNone(result['stdout_yaml']) self.assertEqual( hash(result), hash( ( exec_helpers.ExecResult, cmd, (), (), exec_helpers.ExitCodes.EX_INVALID ) ) )
def test_json(self): """Test json extraction.""" result = exec_helpers.ExecResult("test", stdout=[b'{"test": true}']) self.assertEqual(result.stdout_json, {"test": True})
def exec_result(): return exec_helpers.ExecResult(cmd=command, stdin=None, stdout=stdout_src, stderr=stderr_src, exit_code=0)
def test_stdin_none(self): result = exec_helpers.ExecResult(cmd, exit_code=0) self.assertIsNone(result.stdin)
def test_stdin_utf(self): """Test with string in STDIN.""" result = exec_helpers.ExecResult(cmd, stdin="STDIN", exit_code=0) self.assertEqual(result.stdin, "STDIN")