Esempio n. 1
0
File: main.py Progetto: Godhart/fvf
 def rpyc_send(self, data):
     """
     Sends data to app via stdin
     :param data: Data to send over stdin. Could be an item like str, bytearray or list/tuple of items
     :return: True if data were sent successfully, otherwise - False
     """
     start_time = time.time()
     if (self._mock is None or data == 'exit') and self._connection is None:
         return proto_failure("No connection. Ensure start is complete")
     try:
         if not isinstance(data, (list, tuple)):
             data = data,
         for m in data:
             if self._mock is None or data == 'exit':  # TODO: why data=='exit' overrides self._mock?
                 self._connection.root.send(m)
             else:
                 try:
                     if self._mock_eval:
                         r = evaluate(m)
                     else:
                         r = m
                 except Exception as e:
                     r = None
                 self._mock.append(str(r))
         if self._mock is None or data == 'exit':  # TODO: why data=='exit' overrides self._mock?
             self._connection.root.flush()
     except Exception as e:
         eprint("Platform {}: exception occurred during send: {}".format(
             self.name, e))
         exprint()
         return proto_failure(
             "Failed to send due to exception {}".format(e), -2)
     tprint("rpyc_send elapsed {}".format(time.time() - start_time))
     return proto_success(None)
Esempio n. 2
0
File: main.py Progetto: Godhart/fvf
    def _start(self, reply_contexts):
        """
        1. Update's host from parent platform if necessary
        2. Connects to a Caller
        :return: True if started successfully, otherwise - False
        """
        if self._port is None and self._service is None:
            eprint(
                "Platform {} failed to start - port or service should be specified"
                .format(self.name))
            return proto_failure(
                "Platform {} failed to start - port or service should be specified"
            )

        if self._port is not None and self._service is not None:
            eprint(
                "Platform {} failed to start - specify only port or service, but not both"
                .format(self.name))
            return proto_failure(
                "Platform {} failed to start - port or service should be specified"
            )

        if self._host is None and self.parent is not None:
            c = self.request(
                new_message("platformix", "get", "host"),
                self._generic_request_handler, [], {
                    "on_success":
                    lambda d: setattr(self, "_host", d["host"]),
                    "on_failure":
                    lambda d: eprint("Failed to get host due to {}:{}".format(
                        d["errcode"], d["state"]))
                })

        if self._host is None:
            eprint("Platform {} failed to start - can't get host".format(
                self.name))
            return proto_failure("Failed to start - can't get host")
        try:
            self._connection = rpyc.connect(self._host, self._port)
            # TODO: use service instead of port if it's specified
            if self._args is not None:
                self._connection.root.set_args(copy.copy(self._args))
            result = self._connection.root.run()
        except Exception as e:
            self._connection = None
            eprint("Platform {} failed to start due to exception {}".format(
                self.name, e))
            exprint()
            return proto_failure("Failed to start due to exception {}", -2)
        if result is False:
            self._connection = None
            eprint("Platform {} failed to start: rpyc server returned False".
                   format(self.name))
            return proto_failure("RPYC server returned False")
        if result and not self._mock:
            if self._start_sequence is not None and len(
                    self._start_sequence) > 0:
                self.rpyc_send(self._start_sequence)
        return super(SoftwareRunner, self)._start(reply_contexts)
Esempio n. 3
0
File: main.py Progetto: Godhart/fvf
    def calculate(self, expression):
        """
        :param expression: string with expression to send to Calc App
        :return: ProtocolReply
        """
        start_time = time.time()
        if self._mock:
            try:
                result = evaluate(expression)
            except ZeroDivisionError:
                result = None
            except Exception as e:
                result = "Platform {}: exception occurred on calculate: {}".format(
                    self.name, e)
                exprint()
                tprint("calculate (with fail) elapsed {}".format(time.time() -
                                                                 start_time))
                return proto_failure(result, -2)
            tprint("calculate elapsed {}".format(time.time() - start_time))
            return proto_success(result)

        # NOTE: mock code just ended here. To avoid nesting there is no else, just flat code

        # TODO: optimize code - now it's way to hard (just send/receive and so much code!!!)
        c = self.request(new_message(self._io_interface, "send", expression),
                         None, [], {},
                         timeout=2.0)  # TODO: decrease timeout
        c_state = self._pop_request_state(c)
        if not self._request_state_is_success(c_state):
            tprint(
                "calculate (with fail result) elapsed {}".format(time.time() -
                                                                 start_time))
            return proto_failure("IO failed to send data")

        c = self.request(new_message(self._io_interface, "receive"),
                         None, [], {},
                         timeout=2.0)  # TODO: decrease timeout
        c_state = self._pop_request_state(c)
        if not self._request_state_is_success(c_state):
            tprint(
                "calculate (with fail result) elapsed {}".format(time.time() -
                                                                 start_time))
            return proto_failure("IO failed to receive response")
        # TODO: convert from string to number
        tprint("calculate elapsed {}".format(time.time() - start_time))
        result = PM.parse(c_state["__message__"]).reply_data["value"]
        if isinstance(
                result, (list, tuple)
        ):  # NOTE: softwarerunner returns list but stream_io returns single item
            result = result[0]
        if result.strip() == 'None':
            result = None
        else:
            try:
                result = int(result)
            except ValueError:
                result = float(result)
        return proto_success(result)
Esempio n. 4
0
File: main.py Progetto: Godhart/fvf
 def rpyc_log(self):
     if self._connection is None:
         return proto_failure("No connection. Ensure start is complete")
     try:
         data = self._connection.root.log
     except Exception as e:
         eprint(
             "Platform {}: exception occurred while getting log: {}".format(
                 self.name, e))
         exprint()
         return proto_failure(
             "Failed to get log due to exception {}".format(e), -2)
     return proto_success(data)
Esempio n. 5
0
File: main.py Progetto: Godhart/fvf
    def call_test(self, *args, **kwargs):
        """ Checks get method of platformix protocol
        """
        try:
            if not self._platformix_call_test(*args, **kwargs):
                return False

        except Exception as e:
            eprint("Exception occurred during test platformix::{}({},{})!".format(
                inspect.currentframe().f_code.co_name, args, kwargs))
            exprint()
            raise e

        return True
Esempio n. 6
0
    def cmd(self, context, message):
        # TODO: call host's method instead
        if not self._accept_cmd(context, message):
            return True

        if message.method not in ("sum", "sub", "mult", "div", "power"):
            self._unhandled(
                context, message,
                "unsupported method! Check scoreboard against interface")
            return True

        if len(message.args) != 2:
            self._unhandled(context, message, "wrong format (expected 2 args)")
            return True

        if any(not isinstance(a, (int, float)) for a in message.args):
            self._handle(context, message, PM.failure("", -2))
            return True

        try:
            if message.method == "sum":
                self._handle(context, message,
                             PM.success(message.args[0] + message.args[1]))
            elif message.method == "sub":
                self._handle(context, message,
                             PM.success(message.args[0] - message.args[1]))
            elif message.method == "mult":
                self._handle(context, message,
                             PM.success(message.args[0] * message.args[1]))
            elif message.method == "div":
                if message.args[1] != 0:
                    self._handle(context, message,
                                 PM.success(message.args[0] / message.args[1]))
                else:
                    self._handle(context, message, PM.success(None))
            elif message.method == "power":
                if message.args[0] == 0 and message.args[1] < 0:
                    self._handle(context, message, PM.success(None))
                else:
                    self._handle(context, message,
                                 PM.success(message.args[0]**message.args[1]))

        except Exception as e:
            eprint("ScoreboardArithAll {}: exception occurred: {}!".format(
                self._host.name, e))
            exprint()
            self._unhandled(context, message,
                            "exception occurred: {}!".format(e))
        return True
Esempio n. 7
0
File: main.py Progetto: Godhart/fvf
    def smoke_test(self, *args, **kwargs):
        """ Shallow checks for core functions of platformix protocol, platform_base component and testenv itself
        """

        try:
            if not self._platformix_smoke_test(*args, **kwargs):
                return False

        except Exception as e:
            eprint("Exception occurred during test platformix::{}({},{})!".format(
                inspect.currentframe().f_code.co_name, args, kwargs))
            exprint()
            raise e

        return True
Esempio n. 8
0
File: main.py Progetto: Godhart/fvf
    def test_arith(self, *args, **kwargs):
        """ Checks how arith functions works
        """

        try:
            if not self._test_arith(*args, **kwargs):
                return False

        except Exception as e:
            eprint("Exception occurred during test arith::{}!".format(
                inspect.currentframe().f_code.co_name, e))
            exprint()
            raise e

        return True
Esempio n. 9
0
File: main.py Progetto: Godhart/fvf
 def rpyc_receive(self, count=1, timeout=1.0):
     """
     Get's data that were sent by app via stdout
     :param count: Amount of lines to receive.
             set count to 0 to receive as much as possible, and at least one message
             set count to -1 to receive as much as possible, but nothing is acceptable too
     :param timeout: Time in seconds to wait for data
     :return: True if successfully received Data, otherwise - False. Data itself is contained in a reply to channel
              and Data is list of strings
     """
     start_time = time.time()
     if not isinstance(count, int) or count < -1:
         raise ValueError(
             "Count should be an integer in a range from -1 and up to +infinity"
         )
     if self._mock is None and self._connection is None:
         return proto_failure("No connection. Ensure start is complete")
     try:
         data = []
         if self._mock is not None:
             data = self._mock[:count]
             self._mock = self._mock[count:]
         else:
             while len(data) < count or count == 0 or count == -1:
                 received = self._connection.root.receive(timeout)
                 if received is None or len(received) == 0:
                     break
                 if isinstance(received, (list, tuple)):
                     data += received
                 else:
                     data.append(received)
     except Exception as e:
         eprint("Platform {}: exception occurred during receive: {}".format(
             self.name, e))
         exprint()
         return proto_failure(
             "Failed to receive due to exception {}".format(e), -2)
     tprint("rpyc_receive elapsed {}".format(time.time() - start_time))
     if 0 < count != len(data):
         return proto_failure("Not all requested data were received")
         # TODO: need a way to return partially received data
     elif count == 0 and len(data) == 0:
         return proto_failure("No data were received")
     else:
         return proto_success(data)
Esempio n. 10
0
 def check_scoreboards(self, include=None, exclude=None):
     try:
         r = self.transaction(
             "#scoreboard",
             new_message("platformix", "get", "scoreboard"),
             more_info=True)  # TODO: add Scoreboard interface
     except Exception as e:
         eprint("Exception occurred on get scoreboard: {}".format(e))
         eprint()
         return False
     if r["result"] is False:
         eprint("Failed to get scoreboard")
         return False
     if len(r["replies"]) == 0:
         eprint("No scoreboards found")
         return False
     print(
         "\n============================================================\n"
         "Scoreboards:")
     summary = {}
     errors = False
     for sname in r["replies"]:
         sdata = r["replies"][sname].reply_data["scoreboard"]
         print("  {}:\n{}".format(sname, pprint.pformat(sdata, indent=4)))
         for f in sdata:
             if f not in summary:
                 summary[f] = sdata[f]
             else:
                 try:
                     summary[f] += sdata[f]
                 except Exception as e:
                     eprint(
                         "Exception occurred on scoreboard summary update: {}"
                         .format(e))
                     exprint()
                     errors = True
     if len(r["replies"]) > 1:
         print("Summary:\n{}".format(pprint.pformat(summary)))
     print("")
     if errors or summary["errors"] > 0 or summary[
             "unhandled"] > 0 or summary["requests"] != summary["success"]:
         return False
     return True
Esempio n. 11
0
File: main.py Progetto: Godhart/fvf
 def _stop(self, reply_contexts):
     """
     1. Sends exit sequence to app via stdin
     2. Receives exit log if necessary
     3. Closes connection to a Caller
     :return:
     """
     try:
         if self._mock is None and self._sock is not None:
             if self._close_sequence is not None:
                 self.tcp_send(self._close_sequence)
                 time.sleep(self._timeout)
             self._sock.close()
     except Exception as e:
         eprint("Platform {} experienced exception on stop: {}".format(self.name, e))
         exprint()
         self._reply_all(reply_contexts, PM.notify("abnormal_stop: experienced exception on stop: {}".format(e)))
     self._sock = None
     return super(TcpIO, self)._stop(reply_contexts)
Esempio n. 12
0
 def _platformix_call(self, context, fake_reply, method, *args, **kwargs):
     """
     Calls host's method
     Call result is returned in a success message as value item
     :param context: messaging context
     :param method: method symbolic name
     :param args: args to method call
     :param kwargs: kwargs to method call
     :return: None
     """
     if hasattr(self.host, method):
         if not callable(getattr(self.host, method)):
             self._reply(
                 context,
                 proto_failure("Attribute {} of {} is a property".format(
                     property, self.host.name)), fake_reply)
             return
         try:
             result = getattr(self.host, method)(*args, **kwargs)
         except Exception as e:
             eprint(
                 "Platformix protocol: failed to call method {} of {} with args {}, kwargs {} "
                 "due to exception {}".format(method, self.host.name, args,
                                              kwargs, e))
             exprint()
             self._reply(
                 context,
                 proto_failure(
                     "Failed to call method {} of {} with args {}, kwargs {} "
                     "due to exception {}".format(method, self.host.name,
                                                  args, kwargs, e)),
                 fake_reply)
             return
         self._reply(context, proto_success(result), fake_reply)
     else:
         self._reply(
             context,
             proto_failure("Method {} not found on {}".format(
                 property, self.host.name)), fake_reply)
Esempio n. 13
0
File: main.py Progetto: Godhart/fvf
    def _start(self, reply_contexts):
        """
        1. Update's host from parent platform if necessary
        2. Connects to a Caller
        :return: True if started successfully, otherwise - False
        """
        if self._port is None:
            eprint("Platform {} failed to start - port should be specified".format(self.name))
            return proto_failure("Platform {} failed to start - port or service should be specified")

        if self._host is None and self.parent is not None:
            c = self.request(new_message("platformix", "get", "host"),
                             self._generic_request_handler,
                             [], {"on_success": lambda d: setattr(self, "_host", d["host"]),
                                  "on_failure": lambda d: eprint("Failed to get host due to {}:{}".format(
                                      d["errcode"], d["state"]))
                                  })

        if self._host is None:
            eprint("Platform {} failed to start - can't get host".format(self.name))
            return proto_failure("Failed to start - can't get host")
        try:
            timeout = time.time() + self._connect_timeout
            while True:
                try:
                    if self._mock is None:
                        self._sock = sock = socket.socket()
                        sock.connect((self._host, self._port))
                        sock.settimeout(self._timeout)
                        break
                except ConnectionRefusedError as e:
                    if time.time() > timeout:
                        raise e
        except Exception as e:
            self._sock = None
            eprint("Platform {} failed to start due to exception {}".format(self.name, e))
            exprint()
            return proto_failure("Failed to start due to exception {}", -2)
        return super(TcpIO, self)._start(reply_contexts)
Esempio n. 14
0
 def _platformix_set(self, context, fake_reply, prop, value):
     """
     Set host's property to a value
     :param context: messaging context
     :param prop: property symbolic name
     :param value: value to set
     :return: None
     """
     if hasattr(self.host, prop):
         if not callable(getattr(self.host, prop)):
             try:
                 setattr(self.host, prop, value)
             except Exception as e:
                 eprint(
                     "Platformix protocol: failed to set attribute {} of {} to value {} "
                     "due to exception {}".format(prop, self.host.name,
                                                  value, e))
                 exprint()
                 self._reply(
                     context,
                     proto_failure(
                         "Failed to set attribute {} of {} to value {} "
                         "due to exception {}".format(
                             prop, self.host.name, value, e)), fake_reply)
                 return
             self._reply(context,
                         proto_success(getattr(self.host, prop), prop),
                         fake_reply)
         else:
             self._reply(
                 context,
                 proto_failure("Attribute {} of {} is a method".format(
                     prop, self.host.name)), fake_reply)
     else:
         self._reply(
             context,
             proto_failure("Property {} not found on {}".format(
                 prop, self.host.name)), fake_reply)
Esempio n. 15
0
File: main.py Progetto: Godhart/fvf
 def tcp_send(self, data):
     """
     Sends data to app via stdin
     :param data: Data to send over stdin. Could be an item like str, bytearray or list/tuple of items
     :return: True if data were sent successfully, otherwise - False
     """
     start_time = time.time()
     if self._mock is None and self._sock is None:
         return proto_failure("No connection. Ensure start is complete")
     try:
         if not isinstance(data, (list, tuple)):
             data = data,
         for m in data:
             if self._mock is None:
                 if not isinstance(m, bytearray):
                     if isinstance(m, str):
                         m = m.encode('UTF-8')
                     else:
                         return proto_failure("Send data is expected to be a string, bytearray or "
                                              "list/tuple of strings and bytearrays")
                 self._sock.sendall(m)
             else:
                 try:
                     if self._mock_eval and isinstance(m, str):
                         r = evaluate(m)
                     else:
                         r = m
                 except Exception as e:
                     r = None
                 self._mock.append(str(r))
     except Exception as e:
         eprint("Platform {} failed to send due to exception {}".format(self.name, e))
         exprint()
         return proto_failure("Failed to send due to exception {}".format(e), -2)
     tprint("tcp_send elapsed {}".format(time.time() - start_time))
     return proto_success(None)
Esempio n. 16
0
                "elapsed": 0
            },
            "__platforms_stop__": None
        }
        started = True
        try:
            env.start_platforms()
            results["__platforms_start__"] = {
                "status": True,
                "elapsed": 0
            }  # TODO: start elapsed time
        except Exception as e:
            started = False
            results["__platforms_start__"] = {"status": e, "elapsed": 0}
            eprint("Exception occurred while starting platforms!")
            exprint()
            try:
                env.stop_platforms()
                results["__platforms_stop__"] = {
                    "status": True,
                    "elapsed": 0
                }  # TODO: stop elapsed time
            except Exception as e:
                results["__platforms_stop__"] = {"status": e, "elapsed": 0}
                eprint("Exception occurred while stopping platforms!")
                exprint()
                env.farm.emergency_stop()

        if started:
            # TODO: load stored coverage and scoreboard data if necessary
            pass
Esempio n. 17
0
File: main.py Progetto: Godhart/fvf
    def tcp_receive(self, count=0, timeout=None, decode='UTF-8'):
        """
        Get's data that were sent by app via stdout
        :param count: Amount of bytes to receive.
                set count to 0 to receive as much as possible, at least something
                set count to -1 to receive as much as possible, but nothing is acceptable too
        :param timeout: Time in seconds to wait for data. If None then TCP socket timeout is used
        :param deoode: If not None then received data is decoded into string using specified decoder. Default: 'UTF-8'
        :return: True if successfully received Data, otherwise - False. Data itself is contained in a reply to channel
                 and Data is list of strings
        """
        start_time = time.time()
        if not isinstance(count, int) or count < -1:
            raise ValueError("Count should be an integer in a range from -1 and up to +infinity")
        if self._mock is None and self._sock is None:
            return proto_failure("No connection. Ensure start is complete")
        try:
            if self._mock is not None:
                data = self._mock.pop(0)
            else:
                data = bytearray()
                if count < 1:
                    recv_size = 1024
                else:
                    recv_size = count
                if timeout is not None:
                    timeout = time.time() + timeout
                while len(data) < count or count == 0 or count == -1:
                    try:
                        received = self._sock.recv(recv_size)
                    except TimeoutError:
                        received = None
                    except socket.timeout:
                        received = None

                    if received is None:
                        if count < 0:
                            break
                        if count == 0 and len(data) > 0:
                            break
                    else:
                        data += received

                    if timeout is not None and time.time() > timeout:
                        break

                    if count > 0:
                        recv_size = count - len(data)

                if decode is not None:
                    data = data.decode(decode)

        except Exception as e:
            eprint("Platform {} failed to receive due to exception {}".format(self.name, e))
            exprint()
            return proto_failure("Failed to receive due to exception {}".format(e), -2)
        tprint("rpyc_receive elapsed {}".format(time.time() - start_time))
        if 0 < count != len(data):
            return proto_failure("Not all requested data were received")
            # TODO: need a way to return partially received data
        elif count == 0 and len(data) == 0:
            return proto_failure("No data were received")
        else:
            return proto_success(data)
Esempio n. 18
0
    def run_tests(env,
                  tests,
                  start_stop=True,
                  include=None,
                  exclude=None,
                  dry_run=False):
        """
        A General Routine to run all Tests
        Returns dict with test name and it's results.
        True if test passed, False if test failed, None if test wasn't executed at all
        If exception is occurred on test then it's stored as a test's result
        :param env: Test environment in which test would run
        :param tests: List with tests descriptions to run. Each item exected to be a dict
        :param start_stop: If start_stop is True (default) then all platforms are stared before executing test
        and the all platforms are stopped after test has been executed
        :param include: List of test's names to be executed. Other test would be ignored. Set to None to include all
        :param exclude: List of test's names to be excluded from execution. Set to None to avoid exclusion.
        Exclude list takes priority over include
        :param dry_run: Don't run test actually. Just that tests would run
        :return: a dict with test name as key and test result (see run_test description) as value
                 if dry_run specified then test result would be None
        """
        result = {}
        if include is not None:
            includes_not_found = []
            tests_names = [t['name'] for t in tests]
            for test in include:
                if test not in tests_names and test != "_scoreboards_":
                    includes_not_found.append(test)
            if len(includes_not_found) != 0:
                raise ValueError("Tests {} were not found in:\n {}".format(
                    ', '.join(includes_not_found),
                    ' \n '.join([t["name"] for t in tests])))
                # raise ValueError("Tests {} were not found".format(', '.join(includes_not_found)))

        for test in tests:
            k = test["name"]
            if exclude is not None and k in exclude:
                continue
            if include is not None and k not in include:
                continue
            result[k] = None
        for test in tests:
            k = test["name"]
            if exclude is not None and k in exclude:
                continue
            if include is not None and k not in include:
                continue
            try:
                if not dry_run:
                    result[k] = TestRunner.run_test(env, test, start_stop,
                                                    start_stop)
                else:
                    result[k] = None
            except Exception as e:
                # TODO: make sure transaction ended (force it to end if necessary)
                result[k] = {"status": e, "elapsed": 0}
                eprint("Exception occurred on test '{}': {}".format(k, e))
                exprint()
                if start_stop:  # Make sure platforms are stopped
                    try:
                        env.stop_platforms()
                    except Exception as e:  # If it's impossible to stop platforms - break check
                        result["stop_platforms"] = {"status": e, "elapsed": 0}
                        eprint(
                            "Unrecoverable exception occurred during test calc::{}!\n"
                            "Aborting run_tests routine!\n"
                            "Exception: {}".format(k, e))
                        exprint()
                        env.emergency_stop()
                break
        return result
Esempio n. 19
0
    def _extrapolate_string(self, name, path, value, expr, types):
        if not isinstance(value[0], str):
            return False
        data = value[0]
        if not expr:
            if not types:
                m = re.findall(
                    r"\$(s?){(\w+\.?\w+(?:(?:\[\d+\])|(?:\['.+?'\])|(?:\[\".+?\"\]))*)}",
                    data)
                # TODO: avoid escaped chars
            else:
                m = re.findall(r"^\$([bfi]){(.+)}$", data)
        else:
            m = re.findall(r"\$(es?){(.+?)}",
                           data)  # TODO: avoid escaped chars
        if m is None or len(m) == 0:
            return False
        values = {}
        straight = False
        straight_value = None
        for t, k in list(m):
            if k in values:
                continue  # NOTE: it's enough to extrapolate one time
            try:
                if not expr:
                    if not types:
                        tmp = self._get_extrapolated_value(k)
                        # If specified to be string or it's part of value - convert value to string
                        if t == 's' or len(r"$" + t + "{" + k +
                                           "}") != len(data) or name in (
                                               "alias", ):
                            values[k] = str(tmp)
                        else:
                            straight = True
                            straight_value = tmp
                    else:
                        straight = True
                        if len(k > 2) and (k[0] == "'" and k[-1] == "'"
                                           or k[0] == '"' and k[-1] == '"'):
                            vv = k[1:-1]
                        else:
                            vv = k

                        if t == 'b':
                            if vv in ('True', 'False'):
                                straight_value = vv == 'True'
                            else:
                                straight_value = bool(int(vv))
                        elif t == 'f':
                            straight_value = float(vv)
                        else:
                            straight_value = int(vv)
                else:
                    tmp = evaluate(k)
                    if t == 'es' or len(r"$" + t + "{" + k +
                                        "}") != len(data) or name in (
                                            "alias", ):
                        values[k] = str(tmp)
                    else:
                        straight = True
                        straight_value = tmp
            except Exception as e:
                eprint(
                    "Exception occurred while extrapolating {} with value {}."
                    "\n  Failed on {}, exception: {}".format(path, data, k, e))
                exprint()
                raise e
        if straight:
            value[0] = straight_value
        else:
            for t, k in list(m):
                kv = r"\$" + t + "{" + re.escape(k) + "}"
                vprint("Extrapolated {}: {}->{}".format(
                    value[0], kv, values[k]))
                value[0] = re.sub(kv, values[k], value[0])
        return True
Esempio n. 20
0
File: main.py Progetto: Godhart/fvf
    def _stop(self, reply_contexts):
        """
        1. Sends exit sequence to app via stdin
        2. Receives exit log if necessary
        3. Closes connection to a Caller
        :return:
        """
        stop_failed = None
        try:
            if self._connection is not None:  # Check before proceeding as it can be emergency stop
                if self._exit_sequence is not None and len(
                        self._exit_sequence) > 0:
                    self.rpyc_send(self._exit_sequence)
                    exit_time = time.time() + self._stop_timeout
                    forced_stop = False
                else:
                    self._connection.root.stop(
                        "Stopped by intent of SoftwareRunner (_stop)",
                        force=True)
                    exit_time = time.time() + self._stop_timeout
                    forced_stop = True
                while self._connection.root.running and (
                        not forced_stop or time.time() < exit_time):
                    if not self._connection.root.running:
                        break
                    if time.time() >= exit_time and (not forced_stop):
                        self._connection.root.stop(
                            "Forced to stop by intent of SoftwareRunner (_stop)",
                            force=True)
                        exit_time = time.time() + self._stop_timeout
                        forced_stop = True
                        stop_failed = "Not stopped by stop sequence"
                if self._connection.root.running:
                    if stop_failed is not None:
                        stop_failed += ", "
                    else:
                        stop_failed = ""
                    stop_failed += "App not stopped"

                # TODO: check whether isntance is running and call stop explicitly
                if self._display_log_on_stop:
                    data = list(self._connection.root.log)
                    vprint("Platform {}. Exit log: {}".format(
                        self.name, '\n'.join(data)))
                self._connection.close()
        except Exception as e:
            eprint("Platform {} experienced exception on stop: {}".format(
                self.name, e))
            exprint()
            self._reply_all(
                reply_contexts,
                PM.notify(
                    "abnormal_stop: experienced exception on stop: {}".format(
                        e)))
            if stop_failed is not None:
                stop_failed += ", "
            else:
                stop_failed = ""
            stop_failed += "Experienced exception: {}".format(e)

        if stop_failed is not None:
            eprint("Software runner {} failed to stop app properly: {}".format(
                self.name, stop_failed))
            self._reply_all(
                reply_contexts,
                PM.notify("Software runner {} failed to stop app properly: {}".
                          format(self.name, stop_failed)))

        self._connection = None
        super_result = super(SoftwareRunner, self)._stop(reply_contexts)
        if stop_failed:
            return proto_failure(stop_failed)
        else:
            return super_result