def do(): r = callback() if isinstance(r, types.GeneratorType): import workflows workflows.driver(r) # Execute the generator return None return r
def run_test_driver(action_fn): """ This function runs a test driver. A test driver is a workflow (see workflows and workflows.promises for more details) so you can use the yield construct to make asynchronous computations follow a synchronous control flow. The things that you yield needs to be either: - Instances of the Promise class that wraps an asynchronous callback computation - Other generators that will be called in a synchronous fashion You can use this function as a generator, so you can write a test like: @run_test_driver def test_driver(): print "hello 1" yield timeout(500) print "hello 2" yield timeout(500) print "hello 3" if not gps_assert(...): return # if you want to stop the test """ def workflow(): _ = yield hook("gps_started") yield timeout(10) try: action_gen = action_fn() if action_gen is not None: yield action_gen except: import traceback GPS.Logger('TESTSUITE').log( "Driver workflow received an exception %s %s\n%s" % (sys.exc_info()[0], sys.exc_info()[1], traceback.format_exc())) finally: if "GPS_PREVENT_EXIT" not in os.environ: GPS.exit(force=True) # Install a timeout to catch the errors in GPS, if any, before rlimit # kills everything. # Exit GPS 10 seconds before the rlimit expires. If the rlimit # is not set, default to waiting 130 seconds. timeout_seconds = int(os.environ.get('GPS_RLIMIT_SECONDS', '130')) - 10 GPS.Timeout(timeout_seconds * 1000, do_exit) # Run the workflow driver(workflow())
def __func(self, *args, **kwargs): r = func(self, *args, **kwargs) if isinstance(r, types.GeneratorType): self.set_run_in_background(True) promise = workflows.driver(r) promise.then(lambda x: self.set_run_in_background(False), lambda x: self.set_run_in_background(False)) else: promise = Promise() promise.resolve(r) return promise
def join(*args): """ Return a promise that is resolved when all the promises given in argument are also resolved. The returned promise is resolved with a list of the values of all parameter promises:: a = Promise() # or a function returning a promise b = Promise() # or a function returning a promise p = join(a, b) p.then(lambda(a1, b1): pass) # a1 is the value of a, b1 of b or perhaps, when using workflows: @workflows.run_as_workflow def func1(): yield 1 yield 2 def func2(): # directly a python generator yield 3 yield 4 @workflows.run_as_workflow def func3(): a = yield join(func1(), func2()) pass # executed when func1 and func2 have both terminated. # a == (2, 4) :param List(Promise) *args: promises to wait on """ p = Promise() class _Resolver: _count = 0 _result = [None] * len(args) def __init__(self, idx): self.idx = idx def __call__(self, x): """Called when the promise is resolved""" self._result[self.idx] = x _Resolver._count += 1 if _Resolver._count == len(args): p.resolve(self._result) for idx, a in enumerate(args): if isinstance(a, types.GeneratorType): a = workflows.driver(a) a.then(_Resolver(idx)) return p
def __func(self, *args, **kwargs): r = func(self, *args, **kwargs) if isinstance(r, types.GeneratorType): if isinstance(self, Extension): vcs = self.base else: vcs = self vcs.set_run_in_background(True) promise = workflows.driver(r) promise.then(lambda x: vcs.set_run_in_background(False), lambda x: vcs.set_run_in_background(False)) else: promise = Promise() promise.resolve(r) return promise
def run_test_driver(action_fn): """ This function runs a test driver. A test driver is a workflow (see workflows and workflows.promises for more details) so you can use the yield construct to make asynchronous computations follow a synchronous control flow. The things that you yield needs to be either: - Instances of the Promise class that wraps an asynchronous callback computation - Other generators that will be called in a synchronous fashion You can use this function as a generator, so you can write a test like: @run_test_driver def test_driver(): print "hello 1" yield timeout(500) print "hello 2" yield timeout(500) print "hello 3" if not gps_assert(...): return # if you want to stop the test return XFAIL # if you want the testsuite to mark the test as XFAIL """ def workflow(): _ = yield hook("gps_started") yield timeout(10) last_result = None try: action_gen = action_fn() if action_gen is not None: last_result = yield action_gen except Exception: import traceback GPS.Logger('TESTSUITE').log( "Driver workflow received an exception %s %s\n%s" % (sys.exc_info()[0], sys.exc_info()[1], traceback.format_exc())) finally: if "GPS_PREVENT_EXIT" not in os.environ: if last_result in (SUCCESS, FAILURE, NOT_RUN, XFAIL): status = last_result else: status = 0 # In case there was an error in an assert, record the contents # of the console to aid post-mortem investigations if get_exit_status() != SUCCESS: msg = "Exiting with the following in the Console:\n{}".format( GPS.Console().get_text()) GPS.Logger('TESTSUITE').log(msg) GPS.exit(force=True, status=status) # Install a timeout to catch the errors in GPS, if any, before rlimit # kills everything. # Exit GPS 10 seconds before the rlimit expires. If the rlimit # is not set, default to waiting 130 seconds. timeout_seconds = int(os.environ.get('GPS_RLIMIT_SECONDS', '130')) - 10 GPS.Timeout(timeout_seconds * 1000, do_exit) # Run the workflow driver(workflow())