Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xtriggers: documentation #3457

Merged
merged 1 commit into from
Dec 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions cylc/flow/xtriggers/echo.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""An xtrigger function that prints its arguments and never succeeds.

This may be a useful aid to understanding how xtriggers work. Try returning
True (success) and some results dict to pass on to dependent tasks.
def echo(*args, **kwargs):
"""An xtrigger function that prints its arguments and never succeeds.

"""
This may be a useful aid to understanding how xtriggers work. Try returning
True (success) and some results dict to pass on to dependent tasks.

Returns
tuple: (False, {})

def echo(*args, **kwargs):
"""
print("echo: ARGS:", args)
print("echo: KWARGS:", kwargs)
return (False, {})
return False, {}
51 changes: 43 additions & 8 deletions cylc/flow/xtriggers/suite_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""xtrigger function to check a remote suite state.

"""

import os
import sqlite3
from cylc.flow.cycling.util import add_offset

from cylc.flow.cfgspec.glbl_cfg import glbl_cfg
from cylc.flow.cycling.util import add_offset
from cylc.flow.dbstatecheck import CylcSuiteDBChecker
from metomi.isodatetime.parsers import TimePointParser

Expand All @@ -30,8 +27,46 @@ def suite_state(suite, task, point, offset=None, status='succeeded',
message=None, cylc_run_dir=None, debug=False):
"""Connect to a suite DB and query the requested task state.

Reports satisfied only if the remote suite state has been achieved.
Returns all suite state args to pass on to triggering tasks.
* Reports satisfied only if the remote suite state has been achieved.
* Returns all suite state args to pass on to triggering tasks.

Arguments:
suite (str):
The suite to interrogate.
task (str):
The name of the task to query.
offset (str):
The offset between the cycle this xtrigger is used in and the one
it is querying for as an ISO8601 time duration.
e.g. PT1H (one hour).
status (str):
The task status required for this xtrigger to be satisfied.
message (str):
The custom task output required for this xtrigger to be satisfied.
.. note::

This cannot be specified in conjunction with ``status``.

cylc_run_dir (str):
The directory in which the suite to interrogate.

.. note::

This only needs to be supplied if the suite is running in a
different location to what is specified in the global
configuration (usually ``~/cylc-run``).

debug (bool):
Flag to enable debug information.

Returns:
tuple: (satisfied, results)

satisfied (bool):
True if ``satisfied`` else ``False``.
results (dict):
Dictionary containing the args / kwargs which were provided
to this xtrigger (except ``debug``).

"""
cylc_run_dir = os.path.expandvars(
Expand Down Expand Up @@ -61,4 +96,4 @@ def suite_state(suite, task, point, offset=None, status='succeeded',
'message': message,
'cylc_run_dir': cylc_run_dir
}
return (satisfied, results)
return satisfied, results
92 changes: 51 additions & 41 deletions cylc/flow/xtriggers/xrandom.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""xtrigger with a configurable random chance of success.

Used for testing xtriggers.

"""

from random import random, randint
from time import sleep

Expand All @@ -31,46 +25,62 @@
def xrandom(percent, secs=0, _=None, debug=False):
"""Random xtrigger, with configurable sleep and percent success.

Sleep for <sec> seconds, and report satisfied with ~<percent> likelihood.
If satisfied, return a random color and size as the result.
The '_' argument is not used in the function code, but can be used to
Sleep for ``sec`` seconds, and report satisfied with ~``percent``
likelihood.

The ``_`` argument is not used in the function code, but can be used to
specialize the function signature to cycle point or task.

If the percent is zero, it returns that the trigger condition was
not satisfied, and an empty dictionary.
>>> xrandom(0, 0)
(False, {})
Args:
percent (float):
Percent likelihood of passing.
secs (int):
Seconds to sleep before starting the trigger.
_ (object):
Used to allow users to specialize the trigger with extra
parameters.
debug (bool):
Flag to enable debug information.

Examples:
If the percent is zero, it returns that the trigger condition was
not satisfied, and an empty dictionary.
>>> xrandom(0, 0)
(False, {})

If the percent is not zero, but the random percent success is not met,
then it also returns that the trigger condition was not satisfied,
and an empty dictionary.
>>> import sys
>>> mocked_random = lambda: 0.3
>>> sys.modules[__name__].random = mocked_random
>>> xrandom(15.5, 0)
(False, {})
If the percent is not zero, but the random percent success is not met,
then it also returns that the trigger condition was not satisfied,
and an empty dictionary.
>>> import sys
>>> mocked_random = lambda: 0.3
>>> sys.modules[__name__].random = mocked_random
>>> xrandom(15.5, 0)
(False, {})

Finally, if the percent is not zero, and the random percent success is
met, then it returns that the trigger condition was satisfied, and a
dictionary containing random color and size as result.
>>> import sys
>>> mocked_random = lambda: 0.9
>>> sys.modules[__name__].random = mocked_random
>>> mocked_randint = lambda x, y: 1
>>> sys.modules[__name__].randint = mocked_randint
>>> xrandom(99.99, 0)
(True, {'COLOR': 'orange', 'SIZE': 'small'})
Finally, if the percent is not zero, and the random percent success is
met, then it returns that the trigger condition was satisfied, and a
dictionary containing random color and size as result.
>>> import sys
>>> mocked_random = lambda: 0.9
>>> sys.modules[__name__].random = mocked_random
>>> mocked_randint = lambda x, y: 1
>>> sys.modules[__name__].randint = mocked_randint
>>> xrandom(99.99, 0)
(True, {'COLOR': 'orange', 'SIZE': 'small'})

Args:
percent (float): percent likelihood.
secs (int): seconds to sleep before starting the trigger.
_ (object): used to allow users to specialize the trigger
with extra parameters.
debug (bool): flag to enable debug information.
Returns:
A tuple with the trigger flag (bool) which is set to True if the
trigger was evaluated successful, False otherwise, and a random
color and size (dict).
tuple: (satisfied, results)

satisfied (bool):
True if ``satisfied`` else ``False``.
results (dict):
A dictionary containing the following keys:

``COLOR``
A random color (e.g. red, orange, ...)
``SIZE``
A random size (e.g. small, medium, ...) as the result.

"""
sleep(float(secs))
results = {}
Expand All @@ -80,4 +90,4 @@ def xrandom(percent, secs=0, _=None, debug=False):
'COLOR': COLORS[randint(0, len(COLORS) - 1)], # nosec
'SIZE': SIZES[randint(0, len(SIZES) - 1)] # nosec
}
return (satisfied, results)
return satisfied, results