Exemplo n.º 1
0
def main(parser, options, reg):
    suite, suiterc = parse_suite_arg(options, reg)

    if options.markup:
        prefix = '!cylc!'
    else:
        prefix = ''

    config = SuiteConfig(
        suite, suiterc, options,
        load_template_vars(options.templatevars, options.templatevars_file))
    if options.tasks:
        for task in config.get_task_name_list():
            print(prefix + task)
    elif options.alltasks:
        for task in config.get_task_name_list():
            items = ['[runtime][' + task + ']' + i for i in options.item]
            print(prefix + task, end=' ')
            config.pcfg.idump(items,
                              options.sparse,
                              options.pnative,
                              prefix,
                              options.oneline,
                              none_str=options.none_str)
    else:
        config.pcfg.idump(options.item,
                          options.sparse,
                          options.pnative,
                          prefix,
                          options.oneline,
                          none_str=options.none_str)
Exemplo n.º 2
0
 def _test(cp_tz, utc_mode, expected, expected_warnings=0):
     set_utc_mode(utc_mode)
     mock_config = Mock()
     mock_config.cfg = {'cylc': {'cycle point time zone': cp_tz['suite']}}
     mock_config.options.cycle_point_tz = cp_tz['stored']
     SuiteConfig.process_cycle_point_tz(mock_config)
     assert mock_config.cfg['cylc']['cycle point time zone'] == expected
     assert len(caplog.record_tuples) == expected_warnings
     caplog.clear()
Exemplo n.º 3
0
def main(_, options, *args):
    # suite name or file path
    suite, flow_file = parse_suite_arg(options, args[0])

    # extract task host platforms from the suite
    config = SuiteConfig(
        suite, flow_file, options,
        load_template_vars(options.templatevars, options.templatevars_file))

    platforms = {
        config.get_config(['runtime', name, 'platform'])
        for name in config.get_namespace_list('all tasks')
    } - {None, 'localhost'}

    # When "suite run hosts" are formalised as "flow platforms"
    # we can substitute `localhost` for this, in the mean time
    # we will have to assume that flow hosts are configured correctly.

    if not platforms:
        sys.exit(0)

    verbose = cylc.flow.flags.verbose

    # get the cylc version on each platform
    versions = {}
    for platform_name in sorted(platforms):
        platform = get_platform(platform_name)
        cmd = construct_platform_ssh_cmd(['version'], platform)
        if verbose:
            print(cmd)
        proc = procopen(cmd, stdin=DEVNULL, stdout=PIPE, stderr=PIPE)
        out, err = proc.communicate()
        out = out.decode()
        err = err.decode()
        if proc.wait() == 0:
            if verbose:
                print("   %s" % out)
            versions[platform_name] = out.strip()
        else:
            versions[platform_name] = f'ERROR: {err.strip()}'

    # report results
    max_len = max((len(platform_name) for platform_name in platforms))
    print(f'{"platform".rjust(max_len)}: cylc version')
    print('-' * (max_len + 14))
    for platform_name, result in versions.items():
        print(f'{platform_name.rjust(max_len)}: {result}')
    if all((version == CYLC_VERSION for version in versions.values())):
        exit = 0
    elif options.error:
        exit = 1
    else:
        exit = 0
    sys.exit(exit)
Exemplo n.º 4
0
def test_process_runahead_limit(cfg_scheduling, valid, cycling_mode):
    is_integer_mode = cfg_scheduling['cycling mode'] == 'integer'
    mock_config = Mock()
    mock_config.cycling_type = cycling_mode(integer=is_integer_mode)
    mock_config.cfg = {'scheduling': cfg_scheduling}
    if valid:
        SuiteConfig.process_runahead_limit(mock_config)
    else:
        with pytest.raises(SuiteConfigError) as exc:
            SuiteConfig.process_runahead_limit(mock_config)
        assert "bad runahead limit" in str(exc.value).lower()
Exemplo n.º 5
0
def test_missing_initial_cycle_point():
    """Test that validation fails when the initial cycle point is
    missing for datetime cycling"""
    mocked_config = Mock()
    mocked_config.cfg = {
        'scheduling': {
            'cycling mode': None,
            'initial cycle point': None
        }
    }
    with pytest.raises(SuiteConfigError) as exc:
        SuiteConfig.process_initial_cycle_point(mocked_config)
    assert "This suite requires an initial cycle point" in str(exc.value)
Exemplo n.º 6
0
def test_integer_cycling_default_initial_point(cycling_mode):
    """Test that the initial cycle point defaults to 1 for integer cycling
    mode."""
    cycling_mode(integer=True)  # This is a pytest fixture; sets cycling mode
    mocked_config = Mock()
    mocked_config.cfg = {
        'scheduling': {
            'cycling mode': 'integer',
            'initial cycle point': None
        }
    }
    SuiteConfig.process_initial_cycle_point(mocked_config)
    assert mocked_config.cfg['scheduling']['initial cycle point'] == '1'
    assert mocked_config.initial_point == loader.get_point(1)
Exemplo n.º 7
0
 def _test(utc_mode, expected, expected_warnings=0):
     mock_glbl_cfg(
         'cylc.flow.config.glbl_cfg', f'''
         [cylc]
             UTC mode = {utc_mode['glbl']}
         ''')
     mock_config = Mock()
     mock_config.cfg = {'cylc': {'UTC mode': utc_mode['suite']}}
     mock_config.options.utc_mode = utc_mode['stored']
     SuiteConfig.process_utc_mode(mock_config)
     assert mock_config.cfg['cylc']['UTC mode'] is expected
     assert get_utc_mode() is expected
     assert len(caplog.record_tuples) == expected_warnings
     caplog.clear()
Exemplo n.º 8
0
 def test_xfunction_attribute_error(self, mock_glbl_cfg):
     """Test for error when a xtrigger function cannot be imported."""
     mock_glbl_cfg(
         'cylc.flow.platforms.glbl_cfg', '''
         [platforms]
             [[localhost]]
                 hosts = localhost
         ''')
     with TemporaryDirectory() as temp_dir:
         python_dir = Path(os.path.join(temp_dir, "lib", "python"))
         python_dir.mkdir(parents=True)
         capybara_file = python_dir / "capybara.py"
         with capybara_file.open(mode="w") as f:
             # NB: we are not returning a lambda, instead we have a scalar
             f.write("""toucan = lambda: True""")
             f.flush()
         flow_file = Path(temp_dir, "flow.cylc")
         with flow_file.open(mode="w") as f:
             f.write("""
 [scheduling]
     initial cycle point = 2018-01-01
     [[xtriggers]]
         oopsie = capybara()
     [[graph]]
         R1 = '@oopsie => qux'
             """)
             f.flush()
             with pytest.raises(AttributeError) as excinfo:
                 SuiteConfig(suite="capybara_suite", fpath=f.name)
             assert "not found" in str(excinfo.value)
Exemplo n.º 9
0
 def test_xfunction_imports(
         self, mock_glbl_cfg: Fixture, tmp_path: Path,
         xtrigger_mgr: XtriggerManager):
     """Test for a suite configuration with valid xtriggers"""
     mock_glbl_cfg(
         'cylc.flow.platforms.glbl_cfg',
         '''
         [platforms]
             [[localhost]]
                 hosts = localhost
         '''
     )
     python_dir = tmp_path / "lib" / "python"
     python_dir.mkdir(parents=True)
     name_a_tree_file = python_dir / "name_a_tree.py"
     # NB: we are not returning a lambda, instead we have a scalar
     name_a_tree_file.write_text("""name_a_tree = lambda: 'jacaranda'""")
     flow_file = tmp_path / SuiteFiles.FLOW_FILE
     flow_config = """
     [scheduler]
         allow implicit tasks = True
     [scheduling]
         initial cycle point = 2018-01-01
         [[xtriggers]]
             tree = name_a_tree()
         [[graph]]
             R1 = '@tree => qux'
     """
     flow_file.write_text(flow_config)
     suite_config = SuiteConfig(
         suite="name_a_tree", fpath=flow_file, options=Mock(spec=[]),
         xtrigger_mgr=xtrigger_mgr
     )
     assert 'tree' in suite_config.xtrigger_mgr.functx_map
Exemplo n.º 10
0
    def test_family_inheritance_and_quotes(self, mock_glbl_cfg):
        """Test that inheritance does not ignore items, if not all quoted.

        For example:

            inherit = 'MAINFAM<major, minor>', SOMEFAM
            inherit = 'BIGFAM', SOMEFAM

        See bug #2700 for more/
        """
        mock_glbl_cfg(
            'cylc.flow.platforms.glbl_cfg', '''
            [platforms]
                [[localhost]]
                    hosts = localhost
            ''')
        template_vars = {}
        for content in get_test_inheritance_quotes():
            with NamedTemporaryFile() as tf:
                tf.write(content)
                tf.flush()
                config = SuiteConfig('test',
                                     tf.name,
                                     template_vars=template_vars)
                assert 'goodbye_0_major1_minor10' in \
                       (config.runtime['descendants']
                        ['MAINFAM_major1_minor10'])
                assert 'goodbye_0_major1_minor10' in \
                       config.runtime['descendants']['SOMEFAM']
Exemplo n.º 11
0
 def test_xfunction_not_callable(self, mock_glbl_cfg, tmp_path):
     """Test for error when a xtrigger function is not callable."""
     mock_glbl_cfg(
         'cylc.flow.platforms.glbl_cfg',
         '''
         [platforms]
             [[localhost]]
                 hosts = localhost
         '''
     )
     python_dir = tmp_path / "lib" / "python"
     python_dir.mkdir(parents=True)
     not_callable_file = python_dir / "not_callable.py"
     # NB: we are not returning a lambda, instead we have a scalar
     not_callable_file.write_text("""not_callable = 42""")
     flow_file = tmp_path / SuiteFiles.FLOW_FILE
     flow_config = """
     [scheduling]
         initial cycle point = 2018-01-01
         [[xtriggers]]
             oopsie = not_callable()
         [[graph]]
             R1 = '@oopsie => qux'
     """
     flow_file.write_text(flow_config)
     with pytest.raises(ValueError) as excinfo:
         SuiteConfig(suite="suite_with_not_callable", fpath=flow_file,
                     options=Mock(spec=[]))
     assert "callable" in str(excinfo.value)
Exemplo n.º 12
0
 def test_xfunction_attribute_error(self, mock_glbl_cfg, tmp_path):
     """Test for error when a xtrigger function cannot be imported."""
     mock_glbl_cfg(
         'cylc.flow.platforms.glbl_cfg',
         '''
         [platforms]
             [[localhost]]
                 hosts = localhost
         '''
     )
     python_dir = tmp_path / "lib" / "python"
     python_dir.mkdir(parents=True)
     capybara_file = python_dir / "capybara.py"
     # NB: we are not returning a lambda, instead we have a scalar
     capybara_file.write_text("""toucan = lambda: True""")
     flow_file = tmp_path / SuiteFiles.FLOW_FILE
     flow_config = """
     [scheduling]
         initial cycle point = 2018-01-01
         [[xtriggers]]
             oopsie = capybara()
         [[graph]]
             R1 = '@oopsie => qux'
     """
     flow_file.write_text(flow_config)
     with pytest.raises(AttributeError) as excinfo:
         SuiteConfig(suite="capybara_suite", fpath=flow_file,
                     options=Mock(spec=[]))
     assert "not found" in str(excinfo.value)
Exemplo n.º 13
0
 def test_xfunction_imports(self, mock_glbl_cfg):
     """Test for a suite configuration with valid xtriggers"""
     mock_glbl_cfg(
         'cylc.flow.platforms.glbl_cfg', '''
         [platforms]
             [[localhost]]
                 hosts = localhost
         ''')
     with TemporaryDirectory() as temp_dir:
         python_dir = Path(os.path.join(temp_dir, "lib", "python"))
         python_dir.mkdir(parents=True)
         name_a_tree_file = python_dir / "name_a_tree.py"
         with name_a_tree_file.open(mode="w") as f:
             # NB: we are not returning a lambda, instead we have a scalar
             f.write("""name_a_tree = lambda: 'jacaranda'""")
             f.flush()
         flow_file = Path(temp_dir, "flow.cylc")
         with flow_file.open(mode="w") as f:
             f.write("""
 [scheduling]
     initial cycle point = 2018-01-01
     [[xtriggers]]
         tree = name_a_tree()
     [[graph]]
         R1 = '@tree => qux'
             """)
             f.flush()
             suite_config = SuiteConfig(suite="name_a_tree", fpath=f.name)
             config = suite_config
             assert 'tree' in config.xtrigger_mgr.functx_map
Exemplo n.º 14
0
 def test_xfunction_not_callable(self, mock_glbl_cfg):
     """Test for error when a xtrigger function is not callable."""
     mock_glbl_cfg(
         'cylc.flow.platforms.glbl_cfg', '''
         [platforms]
             [[localhost]]
                 hosts = localhost
         ''')
     with TemporaryDirectory() as temp_dir:
         python_dir = Path(os.path.join(temp_dir, "lib", "python"))
         python_dir.mkdir(parents=True)
         not_callable_file = python_dir / "not_callable.py"
         with not_callable_file.open(mode="w") as f:
             # NB: we are not returning a lambda, instead we have a scalar
             f.write("""not_callable = 42""")
             f.flush()
         flow_file = Path(temp_dir, "flow.cylc")
         with flow_file.open(mode="w") as f:
             f.write("""
 [scheduling]
     initial cycle point = 2018-01-01
     [[xtriggers]]
         oopsie = not_callable()
     [[graph]]
         R1 = '@oopsie => qux'
             """)
             f.flush()
             with pytest.raises(ValueError) as excinfo:
                 SuiteConfig(suite="suite_with_not_callable", fpath=f.name)
             assert "callable" in str(excinfo.value)
Exemplo n.º 15
0
def test_queue_config_not_used_not_defined(caplog, tmp_path):
    """Test task not defined vs no used, in queue config."""
    flow_file_content = """
[scheduling]
   [[queues]]
       [[[q1]]]
           members = foo
       [[[q2]]]
           members = bar
   [[dependencies]]
       # foo and bar not used
       graph = "beef => wellington"
[runtime]
   [[beef]]
   [[wellington]]
   [[foo]]
   # bar not even defined
    """
    flow_file = tmp_path / "flow.cylc"
    flow_file.write_text(flow_file_content)
    SuiteConfig(suite="qtest", fpath=flow_file.absolute())
    log = caplog.messages[0].split('\n')
    assert log[0] == "Queue configuration warnings:"
    assert log[1] == "+ q1: ignoring foo (task not used in the graph)"
    assert log[2] == "+ q2: ignoring bar (task not defined)"
Exemplo n.º 16
0
def get_config(suite, opts, template_vars=None):
    """Return a SuiteConfig object for the provided reg / path."""
    try:
        suiterc = get_suite_rc(suite)
    except SuiteServiceFileError:
        # could not find suite, assume we have been given a path instead
        suiterc = suite
        suite = 'test'
    return SuiteConfig(suite, suiterc, opts, template_vars=template_vars)
Exemplo n.º 17
0
def main(parser, options, *args):
    suite1, suite1rc = parse_suite_arg(options, args[0])
    suite2, suite2rc = parse_suite_arg(options, args[1])
    if suite1 == suite2:
        parser.error("You can't diff a single suite.")
    print("Parsing %s (%s)" % (suite1, suite1rc))
    template_vars = load_template_vars(
        options.templatevars, options.templatevars_file)
    config1 = SuiteConfig(suite1, suite1rc, options, template_vars).cfg
    print("Parsing %s (%s)" % (suite2, suite2rc))
    config2 = SuiteConfig(
        suite2, suite2rc, options, template_vars, is_reload=True).cfg

    if config1 == config2:
        print("Suite definitions %s and %s are identical" % (suite1, suite2))
        sys.exit(0)

    print("Suite definitions %s and %s differ" % (suite1, suite2))

    suite1_only = {}
    suite2_only = {}
    diff_1_2 = {}

    diffdict(config1, config2, suite1_only, suite2_only, diff_1_2)

    if n_oone > 0:
        print()
        msg = str(n_oone) + ' items only in ' + suite1 + ' (<)'
        print(msg)
        prdict(suite1_only, '<', nested=options.nested)

    if n_otwo > 0:
        print()
        msg = str(n_otwo) + ' items only in ' + suite2 + ' (>)'
        print(msg)
        prdict(suite2_only, '>', nested=options.nested)

    if n_diff > 0:
        print()
        msg = (str(n_diff) + ' common items differ ' +
               suite1 + '(<) ' + suite2 + '(>)')
        print(msg)
        prdict(diff_1_2, '', diff=True, nested=options.nested)
Exemplo n.º 18
0
def test_process_icp(
        scheduling_cfg: Dict[str, Any], expected_icp: Optional[str],
        expected_opt_icp: Optional[str],
        expected_err: Optional[Tuple[Type[Exception], str]],
        monkeypatch: Fixture, cycling_mode: Fixture):
    """Test SuiteConfig.process_initial_cycle_point().

    "now" is assumed to be 2005-01-02T06:15+0530

    Params:
        scheduling_cfg: 'scheduling' section of workflow config.
        expected_icp: The expected icp value that gets set.
        expected_opt_icp: The expected value of options.icp that gets set
            (this gets stored in the workflow DB).
        expected_err: Exception class expected to be raised plus the message.
    """
    int_cycling_mode = True
    if scheduling_cfg['cycling mode'] == loader.ISO8601_CYCLING_TYPE:
        int_cycling_mode = False
        iso8601.init(time_zone="+0530")
    cycling_mode(integer=int_cycling_mode)
    mocked_config = Mock()
    mocked_config.cfg = {
        'scheduling': scheduling_cfg
    }
    mocked_config.options.icp = None
    monkeypatch.setattr('cylc.flow.config.get_current_time_string',
                        lambda: '20050102T0615+0530')

    if expected_err:
        err, msg = expected_err
        with pytest.raises(err) as exc:
            SuiteConfig.process_initial_cycle_point(mocked_config)
        assert msg in str(exc.value)
    else:
        SuiteConfig.process_initial_cycle_point(mocked_config)
        assert mocked_config.cfg[
            'scheduling']['initial cycle point'] == expected_icp
        assert str(mocked_config.initial_point) == expected_icp
        opt_icp = mocked_config.options.icp
        if opt_icp is not None:
            opt_icp = str(loader.get_point(opt_icp).standardise())
        assert opt_icp == expected_opt_icp
Exemplo n.º 19
0
def main(parser, options, *args):
    suite1_name, suite1_config = parse_suite_arg(options, args[0])
    suite2_name, suite2_config = parse_suite_arg(options, args[1])
    if suite1_name == suite2_name:
        parser.error("You can't diff a single suite.")
    print(f"Parsing {suite1_name} ({suite1_config})")
    template_vars = load_template_vars(options.templatevars,
                                       options.templatevars_file)
    config1 = SuiteConfig(suite1_name, suite1_config, options,
                          template_vars).cfg
    print(f"Parsing {suite2_name} ({suite2_config})")
    config2 = SuiteConfig(suite2_name,
                          suite2_config,
                          options,
                          template_vars,
                          is_reload=True).cfg

    if config1 == config2:
        print(f"Suite definitions {suite1_name} and {suite2_name} are "
              f"identical")
        sys.exit(0)

    print(f"Suite definitions {suite1_name} and {suite2_name} differ")

    suite1_only = {}
    suite2_only = {}
    diff_1_2 = {}

    diffdict(config1, config2, suite1_only, suite2_only, diff_1_2)

    if n_oone > 0:
        print(f'\n{n_oone} items only in {suite1_name} (<)')
        prdict(suite1_only, '<', nested=options.nested)

    if n_otwo > 0:
        print(f'\n{n_otwo} items only in {suite2_name} (>)')
        prdict(suite2_only, '>', nested=options.nested)

    if n_diff > 0:
        print(f'\n{n_diff} common items differ {suite1_name}(<) '
              f'{suite2_name}(>)')
        prdict(diff_1_2, '', diff=True, nested=options.nested)
Exemplo n.º 20
0
def test_valid_rsync_includes_returns_correct_list(tmp_path):
    """Test that the rsync includes in the correct """

    flow_cylc_content = """
    [scheduling]
        initial cycle point = 2020-01-01
        [[dependencies]]
            graph = "blah => deeblah"
    [scheduler]
        install = dir/, dir2/, file1, file2
        allow implicit tasks = True
    """
    flow_cylc = tmp_path.joinpath(SuiteFiles.FLOW_FILE)
    flow_cylc.write_text(flow_cylc_content)

    config = SuiteConfig(suite="rsynctest", fpath=flow_cylc,
                         options=Mock(spec=[]))

    rsync_includes = SuiteConfig.get_validated_rsync_includes(config)
    assert rsync_includes == ['dir/', 'dir2/', 'file1', 'file2']
Exemplo n.º 21
0
def test_process_startcp(startcp: Optional[str], expected: str,
                         monkeypatch: Fixture, cycling_mode: Fixture):
    """Test SuiteConfig.process_start_cycle_point().

    An icp of 1899-05-01T00+0530 is assumed, and "now" is assumed to be
    2005-01-02T06:15+0530

    Params:
        startcp: The start cycle point given by cli option.
        expected: The expected startcp value that gets set.
    """
    iso8601.init(time_zone="+0530")
    cycling_mode(integer=False)
    mocked_config = Mock(initial_point='18990501T0000+0530')
    mocked_config.options.startcp = startcp
    monkeypatch.setattr('cylc.flow.config.get_current_time_string',
                        lambda: '20050102T0615+0530')

    SuiteConfig.process_start_cycle_point(mocked_config)
    assert str(mocked_config.start_point) == expected
Exemplo n.º 22
0
def test_valid_rsync_includes_returns_correct_list():
    """Test that the rsync includes in the correct """

    flow_cylc_content = """
    [scheduling]
        initial cycle point = 2020-01-01
        [[dependencies]]
            graph = "blah => deeblah"
    [scheduler]
        install = dir/, dir2/, file1, file2
        """
    with TemporaryDirectory() as temp_dir:
        flow_cylc = Path(temp_dir, "flow.cylc")
        with flow_cylc.open(mode="w") as f:
            f.write(flow_cylc_content)
            f.flush()

        config = SuiteConfig(suite="rsynctest", fpath=flow_cylc)

        rsync_includes = SuiteConfig.get_validated_rsync_includes(config)
        assert rsync_includes == ['dir/', 'dir2/', 'file1', 'file2']
Exemplo n.º 23
0
def create_suite_config(workflow_directory: Path, suite_name: str,
                        suiterc_content: str) -> SuiteConfig:
    """Create a SuiteConfig object from a suiterc content.

    Args:
        workflow_directory (Path): workflow base directory
        suite_name (str): suite name
        suiterc_content (str): suiterc content
    """
    suite_rc = Path(workflow_directory, "suite.rc")
    with suite_rc.open(mode="w") as f:
        f.write(suiterc_content)
        f.flush()
        return SuiteConfig(suite=suite_name, fpath=f.name)
Exemplo n.º 24
0
def test_process_fcp(scheduling_cfg: dict, options_fcp: Optional[str],
                     expected_fcp: Optional[str],
                     expected_err: Optional[Tuple[Type[Exception], str]],
                     cycling_mode: Fixture):
    """Test SuiteConfig.process_final_cycle_point().

    Params:
        scheduling_cfg: 'scheduling' section of workflow config.
        options_fcp: The fcp set by cli option.
        expected_fcp: The expected fcp value that gets set.
        expected_err: Exception class expected to be raised plus the message.
    """
    if scheduling_cfg['cycling mode'] == loader.ISO8601_CYCLING_TYPE:
        iso8601.init(time_zone="+0530")
        cycling_mode(integer=False)
    else:
        cycling_mode(integer=True)
    mocked_config = Mock(cycling_type=scheduling_cfg['cycling mode'])
    mocked_config.cfg = {
        'scheduling': scheduling_cfg
    }
    mocked_config.initial_point = loader.get_point(
        scheduling_cfg['initial cycle point']).standardise()
    mocked_config.final_point = None
    mocked_config.options.fcp = options_fcp

    if expected_err:
        err, msg = expected_err
        with pytest.raises(err) as exc:
            SuiteConfig.process_final_cycle_point(mocked_config)
        assert msg in str(exc.value)
    else:
        SuiteConfig.process_final_cycle_point(mocked_config)
        assert mocked_config.cfg[
            'scheduling']['final cycle point'] == expected_fcp
        assert str(mocked_config.final_point) == str(expected_fcp)
Exemplo n.º 25
0
def create_task_proxy(task_name: str,
                      suite_config: SuiteConfig,
                      is_startup=False) -> TaskProxy:
    """Create a Task Proxy based on a TaskDef loaded from the SuiteConfig.

    Args:
        task_name (str): task name
        suite_config (SuiteConfig): SuiteConfig object that holds task
            definitions
        is_startup (bool): whether we are starting the workflow or not
    """
    task_def = suite_config.get_taskdef(task_name)
    return TaskProxy(tdef=task_def,
                     start_point=suite_config.start_point,
                     is_startup=is_startup)
Exemplo n.º 26
0
def test_prelim_process_graph(
        scheduling_cfg: Dict[str, Any],
        scheduling_expected: Optional[Dict[str, Any]],
        expected_err: Optional[Tuple[Type[Exception], str]]):
    """Test SuiteConfig.prelim_process_graph().

    Params:
        scheduling_cfg: 'scheduling' section of workflow config.
        scheduling_expected: The expected scheduling section after preliminary
            processing.
        expected_err: Exception class expected to be raised plus the message.
    """
    mock_config = Mock(cfg={
        'scheduling': scheduling_cfg
    })

    if expected_err:
        err, msg = expected_err
        with pytest.raises(err) as exc:
            SuiteConfig.prelim_process_graph(mock_config)
        assert msg in str(exc.value)
    else:
        SuiteConfig.prelim_process_graph(mock_config)
        assert mock_config.cfg['scheduling'] == scheduling_expected
Exemplo n.º 27
0
def test_rsync_includes_will_not_accept_sub_directories(tmp_path):

    flow_cylc_content = """
    [scheduling]
        initial cycle point = 2020-01-01
        [[dependencies]]
            graph = "blah => deeblah"
    [scheduler]
        install = dir/, dir2/subdir2/, file1, file2
    """
    flow_cylc = tmp_path.joinpath(SuiteFiles.FLOW_FILE)
    flow_cylc.write_text(flow_cylc_content)

    with pytest.raises(SuiteConfigError) as exc:
        SuiteConfig(suite="rsynctest", fpath=flow_cylc, options=Mock(spec=[]))
    assert "Directories can only be from the top level" in str(exc.value)
Exemplo n.º 28
0
def test_rsync_includes_will_not_accept_sub_directories():

    flow_cylc_content = """
    [scheduling]
        initial cycle point = 2020-01-01
        [[dependencies]]
            graph = "blah => deeblah"
    [scheduler]
        install = dir/, dir2/subdir2/, file1, file2
        """
    with TemporaryDirectory() as temp_dir:
        flow_cylc = Path(temp_dir, "flow.cylc")
        with flow_cylc.open(mode="w") as f:
            f.write(flow_cylc_content)
            f.flush()

        with pytest.raises(SuiteConfigError) as exc:
            SuiteConfig(suite="rsynctest", fpath=flow_cylc)
        assert "Directories can only be from the top level" in str(exc.value)
Exemplo n.º 29
0
def main(parser, options, reg=None):
    if options.print_hierarchy:
        print("\n".join(get_config_file_hierarchy(reg)))
        return

    if reg is None:
        glbl_cfg().idump(options.item,
                         sparse=options.sparse,
                         oneline=options.oneline,
                         none_str=options.none_str)
        return

    suite, flow_file = parse_suite_arg(options, reg)

    config = SuiteConfig(
        suite, flow_file, options,
        load_template_vars(options.templatevars, options.templatevars_file))

    config.pcfg.idump(options.item,
                      options.sparse,
                      oneline=options.oneline,
                      none_str=options.none_str)
Exemplo n.º 30
0
def test_check_circular(opt, monkeypatch, caplog, tmp_path):
    """Test SuiteConfig._check_circular()."""
    # ----- Setup -----
    caplog.set_level(logging.WARNING, CYLC_LOG)

    options = Mock(spec=[], is_validate=True)
    if opt:
        setattr(options, opt, True)

    flow_config = """
    [scheduling]
        cycling mode = integer
        [[graph]]
            R1 = "a => b => c => d => e => a"
    [runtime]
        [[a, b, c, d, e]]
            script = True
    """
    flow_file = tmp_path.joinpath(SuiteFiles.FLOW_FILE)
    flow_file.write_text(flow_config)

    def SuiteConfig__assert_err_raised():
        with pytest.raises(SuiteConfigError) as exc:
            SuiteConfig(suite='circular', fpath=flow_file, options=options)
        assert "circular edges detected" in str(exc.value)

    # ----- The actual test -----
    SuiteConfig__assert_err_raised()
    # Now artificially lower the limit and re-test:
    monkeypatch.setattr('cylc.flow.config.SuiteConfig.CHECK_CIRCULAR_LIMIT', 4)
    if opt != 'check_circular':
        # Will no longer raise
        SuiteConfig(suite='circular', fpath=flow_file, options=options)
        msg = "will not check graph for circular dependencies"
        assert msg in caplog.text
    else:
        SuiteConfig__assert_err_raised()