Skip to content

Commit

Permalink
feat: process connector (#165)
Browse files Browse the repository at this point in the history
* feat: process connector
* Fix handling of stdin
* Implement handling of binary data
* Use dataclass instead of tuple for better readability

Co-authored-by: Sebastian Kotulla <sebastian.kotulla@de.bosch.com>
  • Loading branch information
cody82 and cody82 authored Oct 14, 2022
1 parent 8818d73 commit f9a8c3e
Show file tree
Hide file tree
Showing 7 changed files with 720 additions and 0 deletions.
6 changes: 6 additions & 0 deletions docs/connectors/CChannels/cc_process.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
cc_process
=========

.. automodule:: pykiso.lib.connectors.cc_process
:members:
:private-members:
32 changes: 32 additions & 0 deletions examples/process.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
auxiliaries:
# Communication auxiliary to access the process connector
com_aux:
connectors:
# Connect to process1
com: process1
type: pykiso.lib.auxiliaries.communication_auxiliary:CommunicationAuxiliary
connectors:
process1:
config:
# Executable to start, can be overriden in the test. Here we execute a python program
executable: C:\Python38\python.exe
# Arguments to use, can be overriden in the test
args:
- -c
- print("hello");print("pykiso")
# If the process is invoked by shell
shell: False
# Pipe stderr to read it in the test, otherwise it will be printed on the console
pipe_stderr: True
# Pipe stdout to read it in the test, otherwise it will be printed on the console
pipe_stdout: True
# Attach pipe to stdin to send data to the process, otherwise it will read from the console
pipe_stdin: True
# Read/write process data in text mode
text: True
type: pykiso.lib.connectors.cc_process:CCProcess

test_suite_list:
- suite_dir: test_process
test_filter_pattern: 'test_process.py'
test_suite_id: 1
23 changes: 23 additions & 0 deletions examples/process_binary.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
auxiliaries:
com_aux:
connectors:
com: process1
type: pykiso.lib.auxiliaries.communication_auxiliary:CommunicationAuxiliary
connectors:
process1:
config:
executable: C:\Python38\python.exe
args:
- -c
- print("bla");print("bla2")
shell: False
pipe_stderr: True
pipe_stdout: True
pipe_stdin: True
text: False
type: pykiso.lib.connectors.cc_process:CCProcess

test_suite_list:
- suite_dir: test_process
test_filter_pattern: 'test_process_binary.py'
test_suite_id: 1
80 changes: 80 additions & 0 deletions examples/test_process/test_process.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
##########################################################################
# Copyright (c) 2010-2022 Robert Bosch GmbH
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0.
#
# SPDX-License-Identifier: EPL-2.0
##########################################################################

"""
process connector usage example
******************************
:module: test_process
:synopsis: show how to use the cc_process connector
.. currentmodule:: test_process
"""

import logging
import sys
import time
from pathlib import Path

import pykiso

# as usual import your auxiliairies
from pykiso.auxiliaries import com_aux


@pykiso.define_test_parameters(suite_id=1, case_id=1, aux_list=[com_aux])
class TestProcess(pykiso.BasicTest):
"""In this test we communicate with a python process."""

def test_run(self):
# Get the path of the python executable to start a python process
executable = str(Path(sys.executable).resolve())

# start the process
com_aux.send_message(
{
"command": "start",
"executable": executable,
"args": [
"-c",
# process:
# read line from stdin and write to stdout
# sleep 1s
# print "error" on stderr
# sleep 1s
# print "hello" on stdout
# print "pykiso" on stdout
'import sys;import time;print(sys.stdin.readline().strip());sys.stdout.flush();time.sleep(1);print(\'error\', file=sys.stderr);sys.stderr.flush();time.sleep(1);print("hello");print("pykiso")',
],
}
)

# send "hi" to stdin of the process
com_aux.send_message("hi\n")
recv = com_aux.receive_message()
logging.info(f'Received "{recv}"')
assert recv == {"stdout": "hi\n"}

# check output of process(stdout and stderr)
recv = com_aux.receive_message()
logging.info(f'Received "{recv}"')
assert recv == {"stderr": "error\n"}

recv = com_aux.receive_message()
logging.info(f'Received "{recv}"')
assert recv == {"stdout": "hello\n"}

recv = com_aux.receive_message()
logging.info(f'Received "{recv}"')
assert recv == {"stdout": "pykiso\n"}

recv = com_aux.receive_message()
logging.info(f'Received "{recv}"')
assert recv["exit"] == 0
94 changes: 94 additions & 0 deletions examples/test_process/test_process_binary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
##########################################################################
# Copyright (c) 2010-2022 Robert Bosch GmbH
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0.
#
# SPDX-License-Identifier: EPL-2.0
##########################################################################

"""
process connector usage example
******************************
:module: test_process
:synopsis: show how to use the cc_process connector
.. currentmodule:: test_process
"""

import logging
import sys
import time
from pathlib import Path

import pykiso

# as usual import your auxiliairies
from pykiso.auxiliaries import com_aux


@pykiso.define_test_parameters(suite_id=1, case_id=1, aux_list=[com_aux])
class TestProcess(pykiso.BasicTest):
"""In this test we communicate with a python process."""

def test_run(self):
# Get the path of the python executable to start a python process
executable = str(Path(sys.executable).resolve())

# start the process
com_aux.send_message(
{
"command": "start",
"executable": executable,
"args": [
"-c",
# process:
# read line from stdin and write to stdout
# sleep 1s
# print "error" on stderr
# sleep 1s
# print "hello" on stdout
# sleep 1s
# print "pykiso" on stdout
'import sys;import time;print(sys.stdin.readline().strip());sys.stdout.flush();time.sleep(1);print(\'error\', file=sys.stderr);sys.stderr.flush();time.sleep(1);print("hello");sys.stdout.flush();time.sleep(1);print("pykiso")',
],
}
)

with com_aux.collect_messages():
com_aux.send_message(b"hi\n")
time.sleep(0.5)

while True:
recv = com_aux.receive_message(0.5)
print(f"test: {recv}")
if "exit" in recv:
break
return

# send "hi" to stdin of the process
com_aux.send_message(b"hi\n")
recv = com_aux.receive_message()

recv = com_aux.receive_message()
logging.info(f'Received "{recv}"')
assert recv == {"stdout": b"hi\n"}

# check output of process(stdout and stderr)
recv = com_aux.receive_message()
logging.info(f'Received "{recv}"')
assert recv == {"stderr": b"error\n"}

recv = com_aux.receive_message()
logging.info(f'Received "{recv}"')
assert recv == {"stdout": b"hello\n"}

recv = com_aux.receive_message()
logging.info(f'Received "{recv}"')
assert recv == {"stdout": "pykiso\n"}

recv = com_aux.receive_message()
logging.info(f'Received "{recv}"')
assert recv["exit"] == 0
Loading

0 comments on commit f9a8c3e

Please sign in to comment.