Skip to content

Commit

Permalink
add remote_eval and remote_execute keywords
Browse files Browse the repository at this point in the history
  • Loading branch information
rlehfeld committed May 1, 2024
1 parent 7d27aeb commit adb019d
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 0 deletions.
25 changes: 25 additions & 0 deletions RPyCRobotRemote/RPyCRobotRemoteClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@ def sync_request(self, handler, *args, **kwargs):
return sync_request


class Service(rpyc.Service):
"""Extends the simple rpyc.Service with eval and execute"""
__slots__ = ()

def on_connect(self, conn):
"""called when the connection is established"""
super().on_connect(conn)
self._install(conn, conn.root)

@staticmethod
def _install(conn, slave):
"""install commands from remote on the client"""
conn.eval = slave.eval
conn.execute = slave.execute


class RPyCRobotRemoteClient:
"""
Implements Remote Client Interface for Robot Framework based on RPyC
Expand Down Expand Up @@ -107,6 +123,7 @@ def __init__(self,
self._client = rpyc.connect(
peer,
port,
service=Service,
config=config,
ipv6=ipv6,
keepalive=True,
Expand Down Expand Up @@ -138,6 +155,14 @@ def __getattr__(self, name: str):
f'{type(self).__name__!r} object has no attribute {name!r}'
)

def remote_eval(self, text):
"""evaluate arbitrary code (using ``eval``) on remote"""
return self._client.eval(text)

def remote_execute(self, text):
"""execute arbitrary code (using ``exec``) on remote"""
self._client.execute(text)

def stop_remote_server(self):
"""Stop remote server."""
self._client.root.stop_remote_server()
Expand Down
14 changes: 14 additions & 0 deletions RPyCRobotRemote/RPyCRobotRemoteServer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
from typing import TextIO, Optional, Union
from robot.libraries.DateTime import convert_time
import rpyc
# pylint: disable=E0611
from rpyc.lib.compat import execute
# pylint: enable=E0611
from rpyc.utils.server import ThreadedServer


Expand Down Expand Up @@ -53,6 +56,7 @@ class Service(rpyc.Service):
"""The root service provided"""
def __init__(self, library):
super().__init__()
self.namespace = {}
self._library = library

if allow_remote_stop:
Expand All @@ -61,6 +65,16 @@ def stop_remote_server():
"""stop server from remote"""
self.stop()

def execute(self, text):
"""execute arbitrary code (using ``exec``)"""
execute(text, self.namespace)

def eval(self, text):
"""evaluate arbitrary code (using ``eval``)"""
# pylint: disable=W0123
return eval(text, self.namespace)
# pylint: enable=W0123

def get_keyword_names(self):
"""return the methods which can be used as keywords"""
get_kw_names = getattr(
Expand Down
5 changes: 5 additions & 0 deletions test/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import numbers
from collections import namedtuple
from robot.api.deco import keyword, not_keyword
from Model import DummyModel


class Region(namedtuple('Region', 'x y width height')):
Expand Down Expand Up @@ -96,3 +97,7 @@ def get_question(self):
def dummy_test(self):
"""keyword which returns an object"""
return self.Dummy()

def model_test(self, model: DummyModel):
"""keyword which returns an object"""
return model.value
12 changes: 12 additions & 0 deletions test/test.robot
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*** Settings ***
Library RPyCRobotRemote localhost 18861 timeout=10 min WITH NAME RPyCTest
Library Model
Library Collections

*** Test Cases ***
Expand All @@ -15,6 +16,17 @@ Test Remote
Log ${obj.value2}
${obj.value2} Set Variable ${10}

Test Exec
RPyCTest.Remote Execute import math

Test Eval
${math} RPyCTest.Remote Eval math
${ret} Call Method ${math} ceil ${2.5}

Test Model
${obj} Model.Get Model
${ret} RPyCTest.Model Test ${obj}

Test Region Scalar
${region} RPyCTest.Get Region

Expand Down

0 comments on commit adb019d

Please sign in to comment.