Пример #1
0
async def scan_one(reg, host, port, timeout=None, methods=None):
    if not methods:
        methods = ['identify']

    if is_remote_host(host):
        try:
            host = get_host_ip_by_name(host)  # IP reduces DNS traffic
        except socket.error as exc:
            if cylc.flow.flags.debug:
                raise
            sys.stderr.write("ERROR: %s: %s\n" % (exc, host))
            return (reg, host, port, None)

    # NOTE: Connect to the suite by host:port, this was the
    #       SuiteRuntimeClient will not attempt to check the contact file
    #       which would be unnecessary as we have already done so.
    # NOTE: This part of the scan *is* IO blocking.
    client = SuiteRuntimeClient(reg, host=host, port=port, timeout=timeout)

    result = {}
    for method in methods:
        # work our way up the chain of identity methods, extract as much
        # information as we can before the suite rejects us
        try:
            msg = await client.async_request(method)
        except ClientTimeout as exc:
            LOG.exception(f"Timeout: name:{reg}, host:{host}, port:{port}")
            return (reg, host, port, MSG_TIMEOUT)
        except ClientError as exc:
            LOG.exception("ClientError")
            return (reg, host, port, result or None)
        else:
            result.update(msg)
    return (reg, host, port, result)
Пример #2
0
def main(parser, options, suite, *task_globs):
    if not options.state and not options.outputs:
        parser.error("Neither --state=STATE nor --output=OUTPUT is set")

    if options.state == "spawn":
        # Back compat.
        sys.stderr.write(
            "'cylc reset -s spawn' is deprecated; calling 'cylc spawn'\n")
        cmd = sys.argv[0].replace('reset', 'spawn')
        try:
            os.execvp(cmd, [cmd] + task_globs)
        except OSError as exc:
            if exc.filename is None:
                exc.filename = cmd
            raise SystemExit(exc)

    if not options.state:
        options.state = ''

    prompt('Reset task(s) %s in %s' % (task_globs, suite), options.force)
    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port, options.comms_timeout)
    pclient(
        'reset_task_states', {
            'task_globs': task_globs,
            'state': options.state,
            'outputs': options.outputs
        })
Пример #3
0
def main(parser, options, suite, event_msg, event_id):
    LOG.info('Send to suite %s: "%s" (%s)', suite, event_msg, event_id)

    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port)

    max_n_tries = int(options.max_n_tries)
    retry_intvl_secs = float(options.retry_intvl_secs)

    for i_try in range(max_n_tries):
        try:
            pclient('put_ext_trigger', {
                'message': event_msg,
                'id': event_id
            },
                    timeout=options.comms_timeout)
        except ClientError as exc:
            LOG.exception(exc)
            LOG.info(MSG_SEND_FAILED, i_try + 1, max_n_tries)
            if i_try == max_n_tries - 1:  # final attempt
                raise CylcError('send failed')
            else:
                LOG.info(MSG_SEND_RETRY, retry_intvl_secs,
                         options.comms_timeout)
                sleep(retry_intvl_secs)
        else:
            if i_try > 0:
                LOG.info(MSG_SEND_SUCCEED, i_try + 1, max_n_tries)
            break
Пример #4
0
def main(parser, options, suite, event_msg, event_id):
    LOG.info('Send to suite %s: "%s" (%s)', suite, event_msg, event_id)

    pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout)

    max_n_tries = int(options.max_n_tries)
    retry_intvl_secs = float(options.retry_intvl_secs)

    mutation_kwargs = {
        'request_string': MUTATION,
        'variables': {
            'wFlows': [suite],
            'eventMsg': event_msg,
            'eventId': event_id,
        }
    }

    for i_try in range(max_n_tries):
        try:
            pclient('graphql', mutation_kwargs)
        except ClientError as exc:
            LOG.exception(exc)
            LOG.info(MSG_SEND_FAILED, i_try + 1, max_n_tries)
            if i_try == max_n_tries - 1:  # final attempt
                raise CylcError('send failed')
            LOG.info(MSG_SEND_RETRY, retry_intvl_secs, options.comms_timeout)
            sleep(retry_intvl_secs)
        else:
            if i_try > 0:
                LOG.info(MSG_SEND_SUCCEED, i_try + 1, max_n_tries)
            break
Пример #5
0
def main(parser, options, suite, *task_globs):
    prompt('remove task(s) %s in %s' % (task_globs, suite), options.force)
    pclient = SuiteRuntimeClient(
        suite, options.owner, options.host, options.port,
        options.comms_timeout)
    pclient(
        'remove_tasks',
        {'tasks': task_globs, 'spawn': (not options.no_spawn)}
    )
Пример #6
0
def main(parser, options, suite):
    pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout)

    query_kwargs = {'request_string': QUERY, 'variables': {'wFlows': [suite]}}

    result = pclient('graphql', query_kwargs)

    for workflow in result['workflows']:
        print(workflow['cylcVersion'])
Пример #7
0
def main():
    parser = COP(__doc__, comms=True, argdoc=[('REG', 'Suite name')])

    (options, args) = parser.parse_args()
    suite = args[0]

    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port)
    print(pclient('get_cylc_version', timeout=options.comms_timeout))
Пример #8
0
def main(parser, options, suite, *task_globs):
    """CLI of "cylc kill"."""
    if task_globs:
        prompt('Kill task %s in %s' % (task_globs, suite), options.force)
    else:
        prompt('Kill ALL tasks in %s' % (suite), options.force)
    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port)
    pclient('kill_tasks', {'tasks': task_globs}, timeout=options.comms_timeout)
Пример #9
0
def main(parser, options, suite):
    pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout)

    mutation_kwargs = {
        'request_string': MUTATION,
        'variables': {
            'wflows': [suite]
        }
    }

    pclient('graphql', mutation_kwargs)
Пример #10
0
def main(parser, options, suite, *task_globs):
    if task_globs:
        prompt('Poll task %s in %s' % (task_globs, suite), options.force)
    else:
        prompt('Poll ALL tasks in %s' % (suite), options.force)
    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port, options.comms_timeout)
    pclient('poll_tasks', {
        'tasks': task_globs,
        'poll_succeeded': options.poll_succ
    })
Пример #11
0
def main(parser, options, workflow):
    workflow = os.path.normpath(workflow)
    pclient = SuiteRuntimeClient(workflow, timeout=options.comms_timeout)

    mutation_kwargs = {
        'request_string': MUTATION,
        'variables': {
            'wFlows': [workflow],
        }
    }

    pclient('graphql', mutation_kwargs)
Пример #12
0
def main(parser, options, suite, *task_globs):
    pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout)

    mutation_kwargs = {
        'request_string': MUTATION,
        'variables': {
            'wFlows': [suite],
            'tasks': list(task_globs),
        }
    }

    pclient('graphql', mutation_kwargs)
Пример #13
0
def main(_, options, suite, name):
    pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout)

    mutation_kwargs = {
        'request_string': MUTATION,
        'variables': {
            'wFlows': [suite],
            'cName': name,
        }
    }

    pclient('graphql', mutation_kwargs)
Пример #14
0
def main(parser, options, suite, shutdown_arg=None):
    if shutdown_arg is not None and options.kill:
        parser.error("ERROR: --kill is not compatible with [STOP]")

    if options.kill and options.now:
        parser.error("ERROR: --kill is not compatible with --now")

    if options.flow_label and int(options.max_polls) > 0:
        parser.error("ERROR: --flow is not compatible with --max-polls")

    pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout)

    if int(options.max_polls) > 0:
        # (test to avoid the "nothing to do" warning for # --max-polls=0)
        spoller = StopPoller(pclient, "suite stopped", options.interval,
                             options.max_polls)

    # mode defaults to 'Clean'
    mode = None
    task = None
    cycle_point = None
    if shutdown_arg is not None and TaskID.is_valid_id(shutdown_arg):
        # STOP argument detected
        task = shutdown_arg
    elif shutdown_arg is not None:
        # not a task ID, may be a cycle point
        cycle_point = shutdown_arg
    elif options.kill:
        mode = 'Kill'
    elif options.now > 1:
        mode = 'NowNow'
    elif options.now:
        mode = 'Now'

    mutation_kwargs = {
        'request_string': MUTATION,
        'variables': {
            'wFlows': [suite],
            'stopMode': mode,
            'cyclePoint': cycle_point,
            'clockTime': options.wall_clock,
            'task': task,
            'flowLabel': options.flow_label,
        }
    }

    pclient('graphql', mutation_kwargs)

    if int(options.max_polls) > 0:
        # (test to avoid the "nothing to do" warning for # --max-polls=0)
        if not spoller.poll():
            sys.exit(1)
Пример #15
0
def main(parser, options, suite, severity_str):
    try:
        severity = LOGGING_LVL_OF[severity_str]
    except KeyError:
        parser.error("Illegal logging level, %s" % severity_str)

    prompt("Set logging level to %s in %s" % (severity_str, suite),
           options.force)
    pclient = SuiteRuntimeClient(
        suite, options.owner, options.host, options.port,
        options.comms_timeout)

    pclient('set_verbosity', {'level': severity})
Пример #16
0
 def setUp(self) -> None:
     super(TestSuiteRuntimeClient, self).setUp()
     self.scheduler.data_store_mgr = DataStoreMgr(self.scheduler)
     for name in self.scheduler.config.taskdefs:
         task_proxy = create_task_proxy(
             task_name=name,
             suite_config=self.suite_config,
             is_startup=True
         )
         warnings = self.task_pool.insert_tasks(
             items=[task_proxy.identity],
             stopcp=None,
             check_point=True
         )
         assert warnings == 0
     self.task_pool.release_runahead_tasks()
     self.scheduler.data_store_mgr.initiate_data_model()
     self.workflow_id = self.scheduler.data_store_mgr.workflow_id
     create_auth_files(self.suite_name)  # auth keys are required for comms
     barrier = Barrier(2, timeout=20)
     self.server = SuiteRuntimeServer(
         self.scheduler,
         context=SERVER_CONTEXT,
         threaded=True,
         barrier=barrier,
         daemon=True)
     port_range = glbl_cfg().get(['suite servers', 'run ports'])
     self.server.start(port_range[0], port_range[-1])
     # barrier.wait() doesn't seem to work properly here
     # so this workaround will do
     while barrier.n_waiting < 1:
         sleep(0.2)
     barrier.wait()
     sleep(0.5)
     self.client = SuiteRuntimeClient(
         self.scheduler.suite,
         host=self.scheduler.host,
         port=self.server.port)
     sleep(0.5)
Пример #17
0
def main(_, options, suite):
    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port, options.comms_timeout)
    summary = pclient('get_suite_state_summary')

    if options.disp_form == "raw":
        print(summary)
    else:
        if options.disp_form != "tasks":
            for key, value in sorted(summary[0].items()):
                print("%s=%s" % (key, value))
        if options.disp_form != "global":
            dump_to_stdout(summary[1], options.sort_by_cycle)
Пример #18
0
async def scan_one(reg, host, port, pub_port, api, timeout=None, methods=None):
    """Connect to and identify workflow server if possible.

    Args:
        reg (str): Registered name of workflow.
        host (str): Workflow host.
        port (int): Workflow server port.
        pub_port (int): Workflow publisher port.
        api (str): Workflow API version.
        timeout (float, optional): Client socket receiver timeout.
        methods (list): List of methods/endpoints to request.

    Returns:
        tuple: (reg, host, port, pub_port, result)

    """
    if not methods:
        methods = ['identify']

    if is_remote_host(host):
        try:
            host = get_host_ip_by_name(host)  # IP reduces DNS traffic
        except socket.error as exc:
            if cylc.flow.flags.debug:
                raise
            sys.stderr.write("ERROR: %s: %s\n" % (exc, host))
            return (reg, host, port, pub_port, api, None)

    # NOTE: Connect to the suite by host:port, this was the
    #       SuiteRuntimeClient will not attempt to check the contact file
    #       which would be unnecessary as we have already done so.
    # NOTE: This part of the scan *is* IO blocking.
    client = SuiteRuntimeClient(reg, host=host, port=port, timeout=timeout)

    result = {}
    for method in methods:
        # work our way up the chain of identity methods, extract as much
        # information as we can before the suite rejects us
        try:
            msg = await client.async_request(method)
        except ClientTimeout as exc:
            LOG.exception(
                "Timeout: name:%s, host:%s, port:%s", reg, host, port)
            return (reg, host, port, pub_port, api, MSG_TIMEOUT)
        except ClientError as exc:
            LOG.exception("ClientError")
            return (reg, host, port, pub_port, api, result or None)
        else:
            result.update(msg)
    return (reg, host, port, pub_port, api, result)
Пример #19
0
def record_messages(suite, task_job, messages):
    """Record task job messages.

    Print the messages according to their severity.
    Write the messages in the job status file.
    Send the messages to the suite, if possible.

    Arguments:
        suite (str): Suite name.
        task_job (str): Task job identifier "CYCLE/TASK_NAME/SUBMIT_NUM".
        messages (list): List of messages "[[severity, message], ...]".
    """
    # Record the event time, in case the message is delayed in some way.
    event_time = get_current_time_string(
        override_use_utc=(os.getenv('CYLC_UTC') == 'True'))
    # Print to stdout/stderr
    for severity, message in messages:
        if severity in STDERR_LEVELS:
            handle = sys.stderr
        else:
            handle = sys.stdout
        handle.write('%s %s - %s\n' % (event_time, severity, message))
        handle.flush()
    # Write to job.status
    _append_job_status_file(suite, task_job, event_time, messages)
    # Send messages
    try:
        pclient = SuiteRuntimeClient(suite)
    except SuiteStopped:
        # on a remote host this means the contact file is not present
        # either the suite is stopped or the contact file is not present
        # on the job host (i.e. comms method is polling)
        # eitherway don't try messaging
        pass
    except Exception:
        # Backward communication not possible
        if cylc.flow.flags.debug:
            import traceback
            traceback.print_exc()
    else:
        mutation_kwargs = {
            'request_string': MUTATION,
            'variables': {
                'wFlows': [suite],
                'taskJob': task_job,
                'eventTime': event_time,
                'messages': messages,
            }
        }
        pclient('graphql', mutation_kwargs)
Пример #20
0
def main(parser, options, suite, *items):
    for i, item in enumerate(items):
        if not TaskID.is_valid_id_2(item):
            raise UserInputError(
                '"%s": invalid task ID (argument %d)' % (item, i + 1))
    prompt('Insert %s in %s' % (items, suite), options.force)

    pclient = SuiteRuntimeClient(
        suite, options.owner, options.host, options.port)

    pclient(
        'insert_tasks',
        {'items': items, 'no_check': options.no_check,
         'stop_point_string': options.stop_point_string},
        timeout=options.comms_timeout
    )
Пример #21
0
def main(parser, options, suite, severity_str):
    try:
        severity = LOG_LEVELS[severity_str]
    except KeyError:
        parser.error("Illegal logging level, %s" % severity_str)

    pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout)

    mutation_kwargs = {
        'request_string': MUTATION,
        'variables': {
            'wFlows': [suite],
            'level': severity,
        }
    }

    pclient('graphql', mutation_kwargs)
Пример #22
0
def main(parser, options, suite, shutdown_arg=None):
    if shutdown_arg is not None and options.kill:
        parser.error("ERROR: --kill is not compatible with [STOP]")

    if options.kill and options.now:
        parser.error("ERROR: --kill is not compatible with --now")

    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port, options.comms_timeout)

    if int(options.max_polls) > 0:
        # (test to avoid the "nothing to do" warning for # --max-polls=0)
        spoller = StopPoller(pclient, "suite stopped", options.interval,
                             options.max_polls)

    if options.wall_clock:
        prompt(
            'Set shutdown at wall clock %s for %s' %
            (options.wall_clock, suite), options.force)
        pclient('set_stop_after_clock_time',
                {'datetime_string': options.wall_clock})
    elif shutdown_arg is not None and TaskID.is_valid_id(shutdown_arg):
        # STOP argument detected
        prompt('Set shutdown after task %s for %s' % (shutdown_arg, suite),
               options.force)
        pclient('set_stop_after_task', {'task_id': shutdown_arg})
    elif shutdown_arg is not None:
        # not a task ID, may be a cycle point
        prompt('Set shutdown at cycle point %s for %s' % (shutdown_arg, suite),
               options.force)
        pclient('set_stop_after_point', {'point_string': shutdown_arg})
    elif options.now > 1:
        prompt('Shut down and terminate %s now' % suite, options.force)
        pclient('stop_now', {'terminate': True})
    elif options.now:
        prompt('Shut down %s now' % suite, options.force)
        pclient('stop_now')
    else:
        prompt('Shut down %s' % suite, options.force)
        pclient('set_stop_cleanly', {'kill_active_tasks': options.kill})

    if int(options.max_polls) > 0:
        # (test to avoid the "nothing to do" warning for # --max-polls=0)
        if not spoller.poll():
            sys.exit(1)
Пример #23
0
async def est_workflow(reg, host, port, pub_port, context=None, timeout=None):
    """Establish communication with workflow, instantiating REQ client."""
    if is_remote_host(host):
        try:
            host = get_host_ip_by_name(host)  # IP reduces DNS traffic
        except socket.error as exc:
            if flags.debug:
                raise
            logger.error("ERROR: %s: %s\n", exc, host)
            return (reg, host, port, pub_port, None)

    # NOTE: Connect to the suite by host:port. This way the
    #       SuiteRuntimeClient will not attempt to check the contact file
    #       which would be unnecessary as we have already done so.
    # NOTE: This part of the scan *is* IO blocking.
    client = SuiteRuntimeClient(reg, context=context, timeout=timeout)
    _, result = await workflow_request(client, 'identify')
    return (reg, host, port, pub_port, client, result)
Пример #24
0
def main(_, options, suite, func):
    pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout)
    if options.no_input:
        kwargs = {}
    else:
        kwargs = json.load(sys.stdin)
    sys.stdin.close()
    res = pclient(func, kwargs)
    if func in PB_METHOD_MAP:
        if 'element_type' in kwargs:
            pb_msg = PB_METHOD_MAP[func][kwargs['element_type']]()
        else:
            pb_msg = PB_METHOD_MAP[func]()
        pb_msg.ParseFromString(res)
        res_msg = MessageToDict(pb_msg)
    else:
        res_msg = res
    sys.stdout.write(json.dumps(res_msg, indent=4) + '\n')
Пример #25
0
def main(parser, options, suite, *task_globs):
    if task_globs:
        prompt('Hold task(s) %s in %s' % (task_globs, suite), options.force)
    elif options.hold_point_string:
        prompt('Hold suite after %s' % options.hold_point_string,
               options.force)
    else:
        prompt('Hold suite %s' % suite, options.force)

    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port)

    if task_globs:
        pclient('hold_tasks', {'task_globs': task_globs},
                timeout=options.comms_timeout)
    elif options.hold_point_string:
        pclient('hold_after_point_string',
                {'point_string': options.hold_point_string},
                timeout=options.comms_timeout)
    else:
        pclient('hold_suite', timeout=options.comms_timeout)
Пример #26
0
def main(parser, options, suite, task_id=None):
    pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout)

    if task_id and not TaskID.is_valid_id(task_id):
        raise UserInputError("Invalid task ID: %s" % task_id)

    flow_kwargs = {
        'request_string': FLOW_QUERY,
        'variables': {
            'wFlows': [suite]
        }
    }
    task_kwargs = {
        'request_string': TASK_QUERY,
    }
    # cylc ping SUITE
    result = pclient('graphql', flow_kwargs)
    msg = ""
    for flow in result['workflows']:
        w_name = flow['name']
        w_port = flow['port']
        w_pub_port = flow['pubPort']
        if cylc.flow.flags.verbose:
            sys.stdout.write(f'{w_name} running on '
                             f'{pclient.host}:{w_port} {w_pub_port}\n')
        # cylc ping SUITE TASKID
        if task_id:
            task, point = TaskID.split(task_id)
            w_id = flow['id']
            task_kwargs['variables'] = {
                'tProxy': f'{w_id}{ID_DELIM}{point}{ID_DELIM}{task}'
            }
            task_result = pclient('graphql', task_kwargs)
            if not task_result.get('taskProxy'):
                msg = "task not found"
            elif task_result['taskProxy']['state'] != TASK_STATUS_RUNNING:
                msg = f"task not {TASK_STATUS_RUNNING}"
            if msg:
                print(cparse(f'<red>{msg}</red>'))
                sys.exit(1)
Пример #27
0
def record_messages(suite, task_job, messages):
    """Record task job messages.

    Print the messages according to their severity.
    Write the messages in the job status file.
    Send the messages to the suite, if possible.

    Arguments:
        suite (str): Suite name.
        task_job (str): Task job identifier "CYCLE/TASK_NAME/SUBMIT_NUM".
        messages (list): List of messages "[[severity, message], ...]".
    """
    # Record the event time, in case the message is delayed in some way.
    event_time = get_current_time_string(
        override_use_utc=(os.getenv('CYLC_UTC') == 'True'))
    # Print to stdout/stderr
    for severity, message in messages:
        if severity in STDERR_LEVELS:
            handle = sys.stderr
        else:
            handle = sys.stdout
        handle.write('%s %s - %s\n' % (event_time, severity, message))
    handle.flush()
    # Write to job.status
    _append_job_status_file(suite, task_job, event_time, messages)
    # Send messages
    try:
        pclient = SuiteRuntimeClient(suite)
    except Exception:
        # Backward communication not possible
        if cylc.flow.flags.debug:
            import traceback
            traceback.print_exc()
    else:
        pclient('put_messages', {
            'task_job': task_job,
            'event_time': event_time,
            'messages': messages
        })
Пример #28
0
class TestSuiteRuntimeClient(CylcWorkflowTestCase):
    """Test the workflow runtime client."""

    suite_name = "five"
    suiterc = """
[meta]
    title = "Inter-cycle dependence + a cold-start task"
[cylc]
    UTC mode = True
[scheduling]
    #runahead limit = 120
    initial cycle point = 20130808T00
    final cycle point = 20130812T00
    [[graph]]
        R1 = "prep => foo"
        PT12H = "foo[-PT12H] => foo => bar"
[visualization]
    initial cycle point = 20130808T00
    final cycle point = 20130808T12
    [[node attributes]]
        foo = "color=red"
        bar = "color=blue"

    """

    def setUp(self) -> None:
        super(TestSuiteRuntimeClient, self).setUp()
        self.scheduler.data_store_mgr = DataStoreMgr(self.scheduler)
        for name in self.scheduler.config.taskdefs:
            task_proxy = create_task_proxy(
                task_name=name,
                suite_config=self.suite_config,
                is_startup=True
            )
            warnings = self.task_pool.insert_tasks(
                items=[task_proxy.identity],
                stopcp=None,
                check_point=True
            )
            assert warnings == 0
        self.task_pool.release_runahead_tasks()
        self.scheduler.data_store_mgr.initiate_data_model()
        self.workflow_id = self.scheduler.data_store_mgr.workflow_id
        create_auth_files(self.suite_name)  # auth keys are required for comms
        barrier = Barrier(2, timeout=20)
        self.server = SuiteRuntimeServer(
            self.scheduler,
            context=SERVER_CONTEXT,
            threaded=True,
            barrier=barrier,
            daemon=True)
        port_range = glbl_cfg().get(['suite servers', 'run ports'])
        self.server.start(port_range[0], port_range[-1])
        # barrier.wait() doesn't seem to work properly here
        # so this workaround will do
        while barrier.n_waiting < 1:
            sleep(0.2)
        barrier.wait()
        sleep(0.5)
        self.client = SuiteRuntimeClient(
            self.scheduler.suite,
            host=self.scheduler.host,
            port=self.server.port)
        sleep(0.5)

    def tearDown(self):
        self.server.stop()
        self.client.stop()

    def test_constructor(self):
        self.assertFalse(self.client.socket.closed)

    def test_serial_request(self):
        """Test GraphQL endpoint method."""
        request_string = f'''
query {{
  workflows(ids: ["{self.workflow_id}"]) {{
    id
  }}
}}
'''

        data = self.client.serial_request(
            'graphql',
            args={'request_string': request_string})
        self.assertEqual(data['workflows'][0]['id'], self.workflow_id)
        pb_msg = self.client.serial_request('pb_entire_workflow')
        pb_data = PB_METHOD_MAP['pb_entire_workflow']()
        pb_data.ParseFromString(pb_msg)
        self.assertEqual(pb_data.workflow.id, self.workflow_id)
Пример #29
0
def main(_, options, suite, *task_args):
    """Implement "cylc show" CLI."""
    pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout)
    json_filter = {}

    if not task_args:
        query = WORKFLOW_META_QUERY
        query_kwargs = {
            'request_string': query,
            'variables': {
                'wFlows': [suite]
            }
        }
        # Print suite info.
        results = pclient('graphql', query_kwargs)
        for workflow in results['workflows']:
            flat_data = flatten_data(workflow)
            if options.json:
                json_filter.update(flat_data)
            else:
                for key, value in sorted(flat_data.items(), reverse=True):
                    ansiprint(
                        f'<bold>{key}:</bold> {value or "<m>(not given)</m>"}')

    task_names = [arg for arg in task_args if TaskID.is_valid_name(arg)]
    task_ids = [arg for arg in task_args if TaskID.is_valid_id_2(arg)]

    if task_names:
        tasks_query = TASK_META_QUERY
        tasks_kwargs = {
            'request_string': tasks_query,
            'variables': {
                'wFlows': [suite],
                'taskIds': task_names
            }
        }
        # Print suite info.
        results = pclient('graphql', tasks_kwargs)
        multi = len(results['tasks']) > 1
        for task in results['tasks']:
            flat_data = flatten_data(task['meta'])
            if options.json:
                json_filter.update({task['name']: flat_data})
            else:
                if multi:
                    print(f'----\nTASK NAME: {task["name"]}')
                for key, value in sorted(flat_data.items(), reverse=True):
                    ansiprint(
                        f'<bold>{key}:</bold> {value or "<m>(not given)</m>"}')

    if task_ids:
        tp_query = TASK_PREREQS_QUERY
        tp_kwargs = {
            'request_string': tp_query,
            'variables': {
                'wFlows': [suite],
                'taskIds': [
                    f'{c}{ID_DELIM}{n}' for n, c in [
                        TaskID.split(t_id)
                        for t_id in task_ids if TaskID.is_valid_id(t_id)
                    ]
                ] + [
                    f'{c}{ID_DELIM}{n}' for c, n in [
                        t_id.rsplit(TaskID.DELIM2, 1)
                        for t_id in task_ids if not TaskID.is_valid_id(t_id)
                    ]
                ]
            }
        }
        results = pclient('graphql', tp_kwargs)
        multi = len(results['taskProxies']) > 1
        for t_proxy in results['taskProxies']:
            task_id = TaskID.get(t_proxy['name'], t_proxy['cyclePoint'])
            if options.json:
                json_filter.update({task_id: t_proxy})
            else:
                if multi:
                    print(f'----\nTASK ID: {task_id}')
                prereqs = []
                for item in t_proxy['prerequisites']:
                    prefix = ''
                    multi_cond = len(item['conditions']) > 1
                    if multi_cond:
                        prereqs.append([
                            True, '', item['expression'].replace('c', ''),
                            item['satisfied']
                        ])
                    for cond in item['conditions']:
                        if multi_cond and not options.list_prereqs:
                            prefix = f'\t{cond["exprAlias"].strip("c")} = '
                        _, _, point, name = cond['taskId'].split(ID_DELIM)
                        cond_id = TaskID.get(name, point)
                        prereqs.append([
                            False, prefix, f'{cond_id} {cond["reqState"]}',
                            cond['satisfied']
                        ])
                if options.list_prereqs:
                    for composite, _, msg, _ in prereqs:
                        if not composite:
                            print(msg)
                else:
                    flat_meta = flatten_data(t_proxy['task']['meta'])
                    for key, value in sorted(flat_meta.items(), reverse=True):
                        ansiprint(f'<bold>{key}:</bold>'
                                  f' {value or "<m>(not given)</m>"}')
                    ansiprint('\n<bold>prerequisites</bold>'
                              ' (<red>- => not satisfied</red>):')
                    if not prereqs:
                        print('  (None)')
                    for _, prefix, msg, state in prereqs:
                        print_msg_state(f'{prefix}{msg}', state)

                    ansiprint('\n<bold>outputs</bold>'
                              ' (<red>- => not completed</red>):')
                    if not t_proxy['outputs']:
                        print('  (None)')
                    for key, val in t_proxy['outputs'].items():
                        print_msg_state(f'{task_id} {key}', val)
                    if t_proxy['extras']:
                        print('\nother:')
                        for key, value in t_proxy['extras'].items():
                            print('  o  %s ... %s' % (key, value))
        if not results['taskProxies']:
            ansiprint(f"<red>No matching tasks found: {task_ids}",
                      file=sys.stderr)
            sys.exit(1)

    if options.json:
        print(json.dumps(json_filter, indent=4))
Пример #30
0
async def harness(mod_flow, mod_scheduler, mod_run, mod_one_conf):
    reg = mod_flow(mod_one_conf)
    schd = mod_scheduler(reg)
    async with mod_run(schd):
        client = SuiteRuntimeClient(reg)
        yield schd, client