def test_action_with_user_supplied_env_vars(self, mock_popen): env_vars = {'key1': 'val1', 'key2': 'val2', 'PYTHONPATH': 'foobar'} mock_process = mock.Mock() mock_process.communicate.return_value = ('', '') mock_popen.return_value = mock_process runner = pythonrunner.get_runner() runner.action = self._get_mock_action_obj() runner.runner_parameters = {'env': env_vars} runner.entry_point = PACAL_ROW_ACTION_PATH runner.container_service = service.RunnerContainerService() runner.pre_run() (_, _, _) = runner.run({'row_index': 4}) _, call_kwargs = mock_popen.call_args actual_env = call_kwargs['env'] for key, value in env_vars.items(): # Verify that a blacklsited PYTHONPATH has been filtered out if key == 'PYTHONPATH': self.assertTrue(actual_env[key] != value) else: self.assertEqual(actual_env[key], value)
def test_simple_inquiry(self): runner = inquirer.get_runner() runner.context = {'user': test_user} runner.action = self._get_mock_action_obj() runner.runner_parameters = runner_params runner.container_service = service.RunnerContainerService() runner.pre_run() mock_inquiry_liveaction_db.context = {"parent": test_parent.id} (status, output, _) = runner.run({}) self.assertEqual(status, LIVEACTION_STATUS_PENDING) self.assertEqual( output, { 'users': [], 'roles': [], 'route': "developers", 'schema': {}, 'ttl': 1440 }) mock_trigger_dispatcher.return_value.dispatch.assert_called_once_with( 'core.st2.generic.inquiry', { 'id': mock_exc_get.id, 'route': "developers" }) mock_request_pause.assert_called_once_with(test_parent, test_user)
def test_stdout_interception_and_parsing(self, mock_popen): values = {'delimiter': ACTION_OUTPUT_RESULT_DELIMITER} # No output to stdout and no result (implicit None) mock_stdout = '%(delimiter)sNone%(delimiter)s' % values mock_stderr = 'foo stderr' mock_process = mock.Mock() mock_process.communicate.return_value = (mock_stdout, mock_stderr) mock_process.returncode = 0 mock_popen.return_value = mock_process runner = python_runner.get_runner() runner.action = self._get_mock_action_obj() runner.runner_parameters = {} runner.entry_point = PASCAL_ROW_ACTION_PATH runner.container_service = service.RunnerContainerService() runner.pre_run() (_, output, _) = runner.run({'row_index': 4}) self.assertEqual(output['stdout'], '') self.assertEqual(output['stderr'], mock_stderr) self.assertEqual(output['result'], 'None') self.assertEqual(output['exit_code'], 0) # Output to stdout, no result (implicit None),return_code 1 and status # failed mock_stdout = 'pre result%(delimiter)sNone%(delimiter)spost result' % values mock_stderr = 'foo stderr' mock_process = mock.Mock() mock_process.communicate.return_value = (mock_stdout, mock_stderr) mock_process.returncode = 1 mock_popen.return_value = mock_process runner = python_runner.get_runner() runner.action = self._get_mock_action_obj() runner.runner_parameters = {} runner.entry_point = PASCAL_ROW_ACTION_PATH runner.container_service = service.RunnerContainerService() runner.pre_run() (status, output, _) = runner.run({'row_index': 4}) self.assertEqual(output['stdout'], 'pre resultpost result') self.assertEqual(output['stderr'], mock_stderr) self.assertEqual(output['result'], 'None') self.assertEqual(output['exit_code'], 1) self.assertEqual(status, 'failed') # Output to stdout, no result (implicit None), return_code 1 and status # succedded mock_stdout = 'pre result%(delimiter)sNone%(delimiter)spost result' % values mock_stderr = 'foo stderr' mock_process = mock.Mock() mock_process.communicate.return_value = (mock_stdout, mock_stderr) mock_process.returncode = 0 mock_popen.return_value = mock_process runner = python_runner.get_runner() runner.action = self._get_mock_action_obj() runner.runner_parameters = {} runner.entry_point = PASCAL_ROW_ACTION_PATH runner.container_service = service.RunnerContainerService() runner.pre_run() (status, output, _) = runner.run({'row_index': 4}) self.assertEqual(output['stdout'], 'pre resultpost result') self.assertEqual(output['stderr'], mock_stderr) self.assertEqual(output['result'], 'None') self.assertEqual(output['exit_code'], 0) self.assertEqual(status, 'succeeded')
def test_stdout_interception_and_parsing(self, mock_popen): values = {'delimiter': ACTION_OUTPUT_RESULT_DELIMITER} # No output to stdout and no result (implicit None) mock_stdout = ['%(delimiter)sNone%(delimiter)s' % values] mock_stderr = ['foo stderr'] mock_process = mock.Mock() mock_process.returncode = 0 mock_popen.return_value = mock_process mock_process.stdout.closed = False mock_process.stderr.closed = False mock_process.stdout.readline = make_mock_stream_readline( mock_process.stdout, mock_stdout) mock_process.stderr.readline = make_mock_stream_readline( mock_process.stderr, mock_stderr) runner = self._get_mock_runner_obj() runner.entry_point = PASCAL_ROW_ACTION_PATH runner.container_service = service.RunnerContainerService() runner.pre_run() (_, output, _) = runner.run({'row_index': 4}) self.assertEqual(output['stdout'], '') self.assertEqual(output['stderr'], mock_stderr[0]) self.assertEqual(output['result'], 'None') self.assertEqual(output['exit_code'], 0) # Output to stdout, no result (implicit None), return_code 1 and status failed mock_stdout = [ 'pre result%(delimiter)sNone%(delimiter)spost result' % values ] mock_stderr = ['foo stderr'] mock_process = mock.Mock() mock_process.returncode = 1 mock_popen.return_value = mock_process mock_process.stdout.closed = False mock_process.stderr.closed = False mock_process.stdout.readline = make_mock_stream_readline( mock_process.stdout, mock_stdout) mock_process.stderr.readline = make_mock_stream_readline( mock_process.stderr, mock_stderr) runner = self._get_mock_runner_obj() runner.entry_point = PASCAL_ROW_ACTION_PATH runner.container_service = service.RunnerContainerService() runner.pre_run() (status, output, _) = runner.run({'row_index': 4}) self.assertEqual(output['stdout'], 'pre resultpost result') self.assertEqual(output['stderr'], mock_stderr[0]) self.assertEqual(output['result'], 'None') self.assertEqual(output['exit_code'], 1) self.assertEqual(status, 'failed') # Output to stdout, no result (implicit None), return_code 1 and status succeeded mock_stdout = [ 'pre result%(delimiter)sNone%(delimiter)spost result' % values ] mock_stderr = ['foo stderr'] mock_process = mock.Mock() mock_process.returncode = 0 mock_popen.return_value = mock_process mock_process.stdout.closed = False mock_process.stderr.closed = False mock_process.stdout.readline = make_mock_stream_readline( mock_process.stdout, mock_stdout) mock_process.stderr.readline = make_mock_stream_readline( mock_process.stderr, mock_stderr) runner = self._get_mock_runner_obj() runner.entry_point = PASCAL_ROW_ACTION_PATH runner.container_service = service.RunnerContainerService() runner.pre_run() (status, output, _) = runner.run({'row_index': 4}) self.assertEqual(output['stdout'], 'pre resultpost result') self.assertEqual(output['stderr'], mock_stderr[0]) self.assertEqual(output['result'], 'None') self.assertEqual(output['exit_code'], 0) self.assertEqual(status, 'succeeded')
def test_action_stdout_and_stderr_is_not_stored_in_db_by_default( self, mock_spawn, mock_popen): # Feature should be disabled by default values = {'delimiter': ACTION_OUTPUT_RESULT_DELIMITER} # Note: We need to mock spawn function so we can test everything in single event loop # iteration mock_spawn.side_effect = blocking_eventlet_spawn # No output to stdout and no result (implicit None) mock_stdout = [ 'pre result line 1\n', '%(delimiter)sTrue%(delimiter)s' % values, 'post result line 1' ] mock_stderr = ['stderr line 1\n', 'stderr line 2\n', 'stderr line 3\n'] mock_process = mock.Mock() mock_process.returncode = 0 mock_popen.return_value = mock_process mock_process.stdout.closed = False mock_process.stderr.closed = False mock_process.stdout.readline = make_mock_stream_readline( mock_process.stdout, mock_stdout, stop_counter=3) mock_process.stderr.readline = make_mock_stream_readline( mock_process.stderr, mock_stderr, stop_counter=3) runner = self._get_mock_runner_obj() runner.entry_point = PASCAL_ROW_ACTION_PATH runner.container_service = service.RunnerContainerService() runner.pre_run() (_, output, _) = runner.run({'row_index': 4}) self.assertEqual(output['stdout'], 'pre result line 1\npost result line 1') self.assertEqual(output['stderr'], 'stderr line 1\nstderr line 2\nstderr line 3\n') self.assertEqual(output['result'], 'True') self.assertEqual(output['exit_code'], 0) output_dbs = ActionExecutionOutput.get_all() self.assertEqual(len(output_dbs), 0) # False is a default behavior so end result should be the same cfg.CONF.set_override(name='stream_output', group='actionrunner', override=False) mock_process = mock.Mock() mock_process.returncode = 0 mock_popen.return_value = mock_process mock_process.stdout.closed = False mock_process.stderr.closed = False mock_process.stdout.readline = make_mock_stream_readline( mock_process.stdout, mock_stdout, stop_counter=3) mock_process.stderr.readline = make_mock_stream_readline( mock_process.stderr, mock_stderr, stop_counter=3) runner.container_service = service.RunnerContainerService() runner.pre_run() (_, output, _) = runner.run({'row_index': 4}) self.assertEqual(output['stdout'], 'pre result line 1\npost result line 1') self.assertEqual(output['stderr'], 'stderr line 1\nstderr line 2\nstderr line 3\n') self.assertEqual(output['result'], 'True') self.assertEqual(output['exit_code'], 0) output_dbs = ActionExecutionOutput.get_all() self.assertEqual(len(output_dbs), 0)