Esempio n. 1
0
def test_instance_no_header(testdata_dir: pathlib.Path,
                            tmp_trestle_dir: pathlib.Path,
                            monkeypatch: MonkeyPatch) -> None:
    """Test behaviour when validating instance with no header."""
    task_template_folder = tmp_trestle_dir / '.trestle/author/test_task/'
    test_template_folder = testdata_dir / 'author/headers/good_templates'
    test_instances_folder = testdata_dir / 'author/headers/empty_headers'
    task_instance_folder = tmp_trestle_dir / 'test_task'

    shutil.copytree(test_template_folder, task_template_folder)

    # copy all files
    shutil.copytree(test_instances_folder, task_instance_folder)

    command_string_validate_content = 'trestle author headers validate -tn test_task'
    monkeypatch.setattr(sys, 'argv', command_string_validate_content.split())
    rc = Trestle().run()
    assert rc == 3

    command_string_validate_content = 'trestle author headers validate -tn test_task -tv 0.0.1'
    monkeypatch.setattr(sys, 'argv', command_string_validate_content.split())
    rc = Trestle().run()
    assert rc == 3

    command_string_validate_content = 'trestle author headers validate -tv 0.0.1'
    monkeypatch.setattr(sys, 'argv', command_string_validate_content.split())
    rc = Trestle().run()
    assert rc == 1
Esempio n. 2
0
def test_run_failure_plan_execute(tmp_path: pathlib.Path,
                                  sample_catalog_minimal: Catalog,
                                  monkeypatch: MonkeyPatch,
                                  caplog: pytest.LogCaptureFixture):
    """Test failure plan execute() in _run on RemoveCmd."""
    # Plant this specific logged error for failing execution in mock_execute:
    logged_error = 'fail_execute'

    def mock_execute(*args, **kwargs):
        raise err.TrestleError(logged_error)

    # Create a temporary file as a valid arg for trestle remove:
    content_type = FileContentType.JSON
    catalog_def_dir, catalog_def_file = test_utils.prepare_trestle_project_dir(
        tmp_path, content_type, sample_catalog_minimal,
        test_utils.CATALOGS_DIR)
    monkeypatch.chdir(tmp_path)
    # Add remarks here, so it is a valid removal target,
    testargs = [
        'trestle', 'create', '-f',
        str(catalog_def_file), '-e', 'catalog.metadata.remarks'
    ]
    monkeypatch.setattr(sys, 'argv', testargs)
    Trestle().run()
    # .. then attempt to remove it here, but mocking a failed execute:
    testargs = [
        'trestle', 'remove', '-f',
        str(catalog_def_file), '-e', 'catalog.metadata.remarks'
    ]
    monkeypatch.setattr(Plan, 'execute', mock_execute)
    monkeypatch.setattr(sys, 'argv', testargs)
    caplog.clear()
    rc = Trestle().run()
    assert rc > 0
Esempio n. 3
0
def test_broken_args(tmp_trestle_dir: pathlib.Path) -> None:
    """Test behaviour on broken arguments."""
    # must be done using sys patching.
    testargs_root = ['trestle', 'create']
    with mock.patch.object(sys, 'argv', testargs_root):
        with pytest.raises(SystemExit) as pytest_wrapped_e:
            Trestle().run()
            assert pytest_wrapped_e.type == SystemExit
            assert pytest_wrapped_e.value.code > 0
    testargs = testargs_root + ['catalog']
    # missing command
    with mock.patch.object(sys, 'argv', testargs):
        with pytest.raises(SystemExit) as pytest_wrapped_e:
            Trestle().run()
            assert pytest_wrapped_e.type == SystemExit
            assert pytest_wrapped_e.value.code > 0
    # missing mandatory args
    testargs = testargs + ['-x', 'json']
    with mock.patch.object(sys, 'argv', testargs):
        with pytest.raises(SystemExit) as pytest_wrapped_e:
            Trestle().run()
            assert pytest_wrapped_e.type == SystemExit
            assert pytest_wrapped_e.value.code > 0
    testargs = testargs + ['-n', 'name']
    # correct behavior
    with mock.patch.object(sys, 'argv', testargs):
        rc = Trestle().run()
    assert rc == 0
    # correct behavior
    testargs[2] = 'bad_name'
    with mock.patch.object(sys, 'argv', testargs):
        with pytest.raises(SystemExit) as pytest_wrapped_e:
            Trestle().run()
    assert pytest_wrapped_e.type == SystemExit
    assert pytest_wrapped_e.value.code > 0
Esempio n. 4
0
def test_broken_args(tmp_trestle_dir: pathlib.Path,
                     monkeypatch: MonkeyPatch) -> None:
    """Test behaviour on broken arguments."""
    # must be done using sys patching.
    testargs_root = ['trestle', 'create', '-t']
    monkeypatch.setattr(sys, 'argv', testargs_root)
    with pytest.raises(SystemExit) as pytest_wrapped_e:
        Trestle().run()
    assert pytest_wrapped_e.type == SystemExit
    assert pytest_wrapped_e.value.code > 0
    testargs = testargs_root + ['catalog']
    # missing command
    monkeypatch.setattr(sys, 'argv', testargs)
    rc = Trestle().run()
    assert rc > 0
    # missing mandatory args
    testargs = testargs + ['-x', 'json']
    monkeypatch.setattr(sys, 'argv', testargs)
    rc = Trestle().run()
    assert rc > 0
    testargs = testargs + ['-o', 'output']
    # correct behavior
    monkeypatch.setattr(sys, 'argv', testargs)
    rc = Trestle().run()
    assert rc == 0
    # correct behavior
    testargs[3] = 'bad_name'
    monkeypatch.setattr(sys, 'argv', testargs)
    with pytest.raises(SystemExit) as pytest_wrapped_e:
        Trestle().run()
    assert pytest_wrapped_e.type == SystemExit
    assert pytest_wrapped_e.value.code > 0
Esempio n. 5
0
def test_run_failure_nonexistent_element(tmp_path: pathlib.Path,
                                         sample_catalog_minimal: Catalog,
                                         monkeypatch: MonkeyPatch):
    """Test failure of _run on RemoveCmd in specifying nonexistent element for removal."""
    # Create a temporary catalog file with responsible-parties
    content_type = FileContentType.JSON
    catalog_def_dir, catalog_def_file = test_utils.prepare_trestle_project_dir(
        tmp_path, content_type, sample_catalog_minimal,
        test_utils.CATALOGS_DIR)

    # 1. self.remove() fails -- Should happen if wildcard is given, or nonexistent element.
    testargs = [
        'trestle', 'remove', '-f',
        str(catalog_def_file), '-e', 'catalog.blah'
    ]
    monkeypatch.setattr(sys, 'argv', testargs)
    exitcode = Trestle().run()
    assert exitcode == 5

    # 2. Corrupt json file
    source_file_path = pathlib.Path.joinpath(test_utils.JSON_TEST_DATA_PATH,
                                             'bad_simple.json')
    shutil.copyfile(source_file_path, catalog_def_file)
    testargs = [
        'trestle', 'remove', '-f',
        str(catalog_def_file), '-e', 'catalog.metadata.roles'
    ]
    monkeypatch.setattr(sys, 'argv', testargs)
    exitcode = Trestle().run()
    assert exitcode == 5
Esempio n. 6
0
def test_href_failures(tmp_path: pathlib.Path, keep_cwd: pathlib.Path,
                       simplified_nist_profile: profile.Profile,
                       monkeypatch: MonkeyPatch) -> None:
    """Test href failure modes."""
    # prepare trestle project dir with the file
    models_path, profile_path = test_utils.prepare_trestle_project_dir(
        tmp_path, FileContentType.JSON, simplified_nist_profile,
        test_utils.PROFILES_DIR)

    cmd_string = 'trestle href -n my_test_model -hr foobar'

    # not in trestle project so fail
    monkeypatch.setattr(sys, 'argv', cmd_string.split())
    rc = Trestle().run()
    assert rc == 5

    os.chdir(models_path)

    cmd_string = 'trestle href -n my_test_model -hr foobar -i 2'

    # add extra import to the profile and ask for import number 2
    simplified_nist_profile.imports.append(simplified_nist_profile.imports[0])
    simplified_nist_profile.oscal_write(profile_path)
    monkeypatch.setattr(sys, 'argv', cmd_string.split())
    rc = Trestle().run()
    assert rc == 1
Esempio n. 7
0
def test_href_cmd(tmp_path: pathlib.Path, keep_cwd: pathlib.Path,
                  simplified_nist_profile: profile.Profile,
                  monkeypatch: MonkeyPatch) -> None:
    """Test basic cmd invocation of href."""
    # prepare trestle project dir with the file
    models_path, profile_path = test_utils.prepare_trestle_project_dir(
        tmp_path, FileContentType.JSON, simplified_nist_profile,
        test_utils.PROFILES_DIR)

    os.chdir(models_path)

    # just list the hrefs
    cmd_string = 'trestle href -n my_test_model'
    monkeypatch.setattr(sys, 'argv', cmd_string.split())
    rc = Trestle().run()
    assert rc == 0

    orig_href = simplified_nist_profile.imports[0].href

    new_href = 'trestle://catalogs/my_catalog/catalog.json'

    cmd_string = f'trestle href -n my_test_model -hr {new_href}'
    monkeypatch.setattr(sys, 'argv', cmd_string.split())
    rc = Trestle().run()
    assert rc == 0

    # confirm new href is correct
    new_profile: profile.Profile = profile.Profile.oscal_read(profile_path)
    assert new_profile.imports[0].href == new_href

    # restore orig href to confirm models are otherwise equivalent
    # only thing different should be last-modified
    new_profile.imports[0].href = orig_href
    assert test_utils.models_are_equivalent(new_profile,
                                            simplified_nist_profile)
Esempio n. 8
0
def test_assemble_catalog_all(
    testdata_dir: pathlib.Path, tmp_trestle_dir: pathlib.Path, monkeypatch: MonkeyPatch
) -> None:
    """Test assembling all catalogs in trestle dir."""
    shutil.rmtree(pathlib.Path('dist'))
    catalogs_dir = tmp_trestle_dir / 'catalogs'
    my_names = ['mycatalog1', 'mycatalog2', 'mycatalog3']
    for my_name in my_names:
        test_data_source = testdata_dir / 'split_merge/step4_split_groups_array/catalogs/mycatalog'
        shutil.copytree(test_data_source, catalogs_dir / my_name)

    testargs = ['trestle', 'assemble', 'catalog', '-t', '-x', 'json']
    monkeypatch.setattr(sys, 'argv', testargs)
    rc = Trestle().run()
    assert rc == 0

    # Read assembled model
    for my_name in my_names:
        _, _, expected_model = ModelUtils.load_distributed(catalogs_dir / f'{my_name}/catalog.json', tmp_trestle_dir)
        actual_model = Catalog.oscal_read(pathlib.Path(f'dist/catalogs/{my_name}.json'))
        assert actual_model == expected_model

    testargs = ['trestle', 'assemble', 'profile', '-t', '-x', 'json']
    # Tests should pass on empty set of directories.
    monkeypatch.setattr(sys, 'argv', testargs)
    rc = Trestle().run()
    assert rc == 0
Esempio n. 9
0
def test_catalog_assemble_failures(tmp_trestle_dir: pathlib.Path,
                                   monkeypatch: MonkeyPatch) -> None:
    """Test failurs of catalog assemble."""
    test_args = 'trestle author catalog-assemble -m foo -o my_md'.split()
    monkeypatch.setattr(sys, 'argv', test_args)
    assert Trestle().run() == 1

    (tmp_trestle_dir / 'foo').mkdir()
    monkeypatch.setattr(sys, 'argv', test_args)
    assert Trestle().run() == 1
Esempio n. 10
0
def test_run_failure(keep_cwd: pathlib.Path, monkeypatch: MonkeyPatch) -> None:
    """Test failure of _run for AddCmd."""
    testargs = ['trestle', 'create', '-e', 'catalog.metadata.roles']
    monkeypatch.setattr(sys, 'argv', testargs)
    rc = Trestle().run()
    assert rc > 0

    testargs = ['trestle', 'create', '-f', './catalog.json']
    monkeypatch.setattr(sys, 'argv', testargs)
    rc = Trestle().run()
    assert rc > 0
Esempio n. 11
0
def test_split_run_failure(
        tmp_path: pathlib.Path,
        sample_target_def: ostarget.TargetDefinition) -> None:
    """Test split run failure."""
    # prepare trestle project dir with the file
    target_def_dir: pathlib.Path = tmp_path / 'target-definitions' / 'mytarget'
    target_def_file: pathlib.Path = target_def_dir / 'target-definition.yaml'
    target_def_dir.mkdir(exist_ok=True, parents=True)
    sample_target_def.oscal_write(target_def_file)
    invalid_file = target_def_dir / 'invalid.file'
    invalid_file.touch()

    cwd = os.getcwd()
    os.chdir(target_def_dir)

    # not a trestle project
    testargs = [
        'trestle', 'split', '-f', 'target-definition.yaml', '-e',
        'target-definition.metadata, target-definition.targets.*'
    ]
    with patch.object(sys, 'argv', testargs):
        with pytest.raises(TrestleError):
            Trestle().run()

    # create trestle project
    test_utils.ensure_trestle_config_dir(tmp_path)

    # no file specified
    testargs = [
        'trestle', 'split', '-e',
        'target-definition.metadata, target-definition.targets.*'
    ]
    with patch.object(sys, 'argv', testargs):
        rc = Trestle().run()
        assert rc > 0
    # check with missing file
    testargs = [
        'trestle', 'split', '-f', 'missing.yaml', '-e',
        'target-definition.metadata, target-definition.targets.*'
    ]
    with patch.object(sys, 'argv', testargs):
        rc = Trestle().run()
        assert rc > 0

    # check with incorrect file type
    testargs = [
        'trestle', 'split', '-f', invalid_file.name, '-e',
        'target-definition.metadata, target-definition.targets.*'
    ]
    with patch.object(sys, 'argv', testargs):
        with pytest.raises(TrestleError):
            Trestle().run()

    os.chdir(cwd)
Esempio n. 12
0
def test_run_failure():
    """Test failure of _run for AddCmd."""
    testargs = ['trestle', 'add', '-e', 'catalog.metadata.roles']
    with patch.object(sys, 'argv', testargs):
        with pytest.raises(err.TrestleError):
            Trestle().run()

    testargs = ['trestle', 'add', '-f', './catalog.json']
    with patch.object(sys, 'argv', testargs):
        with pytest.raises(err.TrestleError):
            Trestle().run()
Esempio n. 13
0
def test_e2e(task_name: str, template_path: pathlib.Path,
             content_path: pathlib.Path, global_: bool, setup_rc: int,
             template_validate_rc: int, validate_rc: int,
             testdata_dir: pathlib.Path, tmp_trestle_dir: pathlib.Path,
             monkeypatch: MonkeyPatch) -> None:
    """Run an E2E workflow with a number of test criteria."""
    command_string_setup = 'trestle author headers setup'
    command_string_create_sample = 'trestle author headers create-sample'
    command_string_validate_template = 'trestle author headers template-validate'
    command_string_validate_content = 'trestle author headers validate -r'
    template_target_loc: pathlib.Path
    if task_name:
        tn_string = f' -tn {task_name}'
        command_string_setup += tn_string
        command_string_create_sample += tn_string
        command_string_validate_template += tn_string
        command_string_validate_content += tn_string
        template_target_loc = tmp_trestle_dir / '.trestle' / 'author' / task_name / START_TEMPLATE_VERSION
    else:
        task_name = 'placeholder'
    if global_:
        global_str = ' --global'
        command_string_setup += global_str
        command_string_create_sample += global_str
        command_string_validate_template += global_str
        command_string_validate_content += global_str
        template_target_loc = tmp_trestle_dir / '.trestle' / 'author' / '__global__' / START_TEMPLATE_VERSION
    test_content_loc = tmp_trestle_dir / task_name / f'{uuid4()}'
    monkeypatch.setattr(sys, 'argv', command_string_setup.split())
    rc = Trestle().run()
    assert rc == setup_rc
    if setup_rc > 0:
        return
    shutil.rmtree(str(template_target_loc))
    shutil.copytree(str(testdata_dir / template_path),
                    str(template_target_loc))

    monkeypatch.setattr(sys, 'argv', command_string_validate_template.split())
    rc = Trestle().run()
    assert rc == template_validate_rc
    if template_validate_rc > 0:
        return

    # Create sample - should always work if we are here.
    monkeypatch.setattr(sys, 'argv', command_string_create_sample.split())
    rc = Trestle().run()
    assert rc == 0

    shutil.copytree(str(testdata_dir / content_path), str(test_content_loc))
    monkeypatch.setattr(sys, 'argv', command_string_validate_content.split())
    rc = Trestle().run()
    assert rc == validate_rc
Esempio n. 14
0
def test_run(tmp_path: pathlib.Path, sample_catalog_missing_roles,
             monkeypatch: MonkeyPatch):
    """Test _run for RemoveCmd."""
    # 1. Test trestle remove for one element.
    # expected catalog after remove of Responsible-Party
    file_path = pathlib.Path.joinpath(
        test_utils.JSON_TEST_DATA_PATH,
        'minimal_catalog_no_responsible-parties.json')
    expected_catalog_no_rp = Catalog.oscal_read(file_path)

    content_type = FileContentType.JSON

    # Create a temporary file with responsible-parties to be removed.
    catalog_def_dir, catalog_def_file = test_utils.prepare_trestle_project_dir(
        tmp_path, content_type, sample_catalog_missing_roles,
        test_utils.CATALOGS_DIR)

    testargs = [
        'trestle', 'remove', '-tr',
        str(tmp_path), '-f',
        str(catalog_def_file), '-e', 'catalog.metadata.responsible-parties'
    ]

    monkeypatch.setattr(sys, 'argv', testargs)
    assert Trestle().run() == 0

    actual_catalog = Catalog.oscal_read(catalog_def_file)
    assert expected_catalog_no_rp == actual_catalog

    # 2. Test trestle remove for multiple comma-separated elements.
    # minimal catalog with Roles and Resposibile-Parties.
    file_path = pathlib.Path.joinpath(test_utils.JSON_TEST_DATA_PATH,
                                      'minimal_catalog_roles.json')
    catalog_with_roles_responsible_parties = Catalog.oscal_read(file_path)

    # Create a temporary file with Roles and Responsible-Parties to be removed.
    catalog_def_dir, catalog_def_file_2 = test_utils.prepare_trestle_project_dir(
        tmp_path, content_type, catalog_with_roles_responsible_parties,
        test_utils.CATALOGS_DIR)

    testargs = [
        'trestle', 'remove', '-tr',
        str(tmp_path), '-f',
        str(catalog_def_file_2), '-e',
        'catalog.metadata.responsible-parties,catalog.metadata.roles'
    ]

    monkeypatch.setattr(sys, 'argv', testargs)
    assert Trestle().run() == 0

    actual_catalog = Catalog.oscal_read(catalog_def_file_2)
    assert expected_catalog_no_rp == actual_catalog
Esempio n. 15
0
def test_split_run_failures(
        keep_cwd: pathlib.Path, tmp_path: pathlib.Path,
        sample_nist_component_def: component.ComponentDefinition,
        monkeypatch: MonkeyPatch) -> None:
    """Test split run failure."""
    # prepare trestle project dir with the file
    component_def_dir: pathlib.Path = tmp_path / 'component-definitions' / 'mytarget'
    component_def_file: pathlib.Path = component_def_dir / 'component-definition.yaml'
    component_def_dir.mkdir(exist_ok=True, parents=True)
    sample_nist_component_def.oscal_write(component_def_file)
    invalid_file = component_def_dir / 'invalid.file'
    invalid_file.touch()

    os.chdir(component_def_dir)

    # not a trestle project
    testargs = [
        'trestle', 'split', '-tr',
        str(tmp_path), '-f', 'component-definition.yaml', '-e',
        'component-definition.metadata, component-definition.components.*'
    ]
    monkeypatch.setattr(sys, 'argv', testargs)
    with pytest.raises(SystemExit) as wrapped_error:
        trestle.cli.run()
        assert wrapped_error.value.code == 1

    # create trestle project
    test_utils.ensure_trestle_config_dir(tmp_path)

    # no file specified and garbage element
    testargs = ['trestle', 'split', '-e', 'foo.bar']
    monkeypatch.setattr(sys, 'argv', testargs)
    rc = Trestle().run()
    assert rc > 0

    # check with missing file
    testargs = [
        'trestle', 'split', '-f', 'missing.yaml', '-e',
        'component-definition.metadata, component-definition.components.*'
    ]
    monkeypatch.setattr(sys, 'argv', testargs)
    rc = Trestle().run()
    assert rc > 0

    # check with incorrect file type
    testargs = [
        'trestle', 'split', '-f', invalid_file.name, '-e',
        'component-definition.metadata, component-definition.components.*'
    ]
    monkeypatch.setattr(sys, 'argv', testargs)
    rc = Trestle().run()
    assert rc == 1
Esempio n. 16
0
def test_run_failure():
    """Test failure of _run for AddCmd."""
    testargs = ['trestle', 'add', '-e', 'catalog.metadata.roles']
    with patch.object(sys, 'argv', testargs):
        with pytest.raises(SystemExit) as e:
            Trestle().run()
        assert e.type == SystemExit
        assert e.value.code == 2

    testargs = ['trestle', 'add', '-f', './catalog.json']
    with patch.object(sys, 'argv', testargs):
        with pytest.raises(SystemExit) as e:
            Trestle().run()
        assert e.type == SystemExit
        assert e.value.code == 2
Esempio n. 17
0
def create_trestle_project_with_model(
    top_dir: pathlib.Path, model_obj: OscalBaseModel, model_name: str, monkeypatch: MonkeyPatch
) -> pathlib.Path:
    """Create initialized trestle project and import the model into it."""
    cur_dir = pathlib.Path.cwd()

    # create subdirectory for trestle project
    trestle_root = top_dir / 'my_trestle'
    trestle_root.mkdir()
    os.chdir(trestle_root)

    try:
        testargs = ['trestle', 'init']
        monkeypatch.setattr(sys, 'argv', testargs)
        assert Trestle().run() == 0

        # place model object in top directory outside trestle project
        # so it can be imported
        tmp_model_path = top_dir / (model_name + '.json')
        model_obj.oscal_write(tmp_model_path)

        i = ImportCmd()
        args = argparse.Namespace(
            trestle_root=trestle_root, file=str(tmp_model_path), output=model_name, verbose=0, regenerate=False
        )
        assert i._run(args) == 0
    except Exception as e:
        raise TrestleError(f'Error creating trestle project with model: {e}')
    finally:
        os.chdir(cur_dir)
    return trestle_root
Esempio n. 18
0
def test_import_profile_with_optional_added(tmp_trestle_dir: pathlib.Path,
                                            monkeypatch: MonkeyPatch) -> None:
    """Create profile, add modify to it, and import."""
    rand_str = ''.join(random.choice(string.ascii_letters) for x in range(16))
    profile_file = f'{tmp_trestle_dir.parent}/{rand_str}.json'
    # create generic profile
    profile_data = generators.generate_sample_model(
        trestle.oscal.profile.Profile)
    # create special parameter and add it to profile
    set_parameter = SetParameter(param_id='my_param', depends_on='my_depends')
    modify = Modify(set_parameters=[set_parameter])
    profile_data.modify = modify
    # write it to place outside trestle directory
    profile_data.oscal_write(pathlib.Path(profile_file))
    # now do actual import into trestle directory with name 'imported'
    test_args = f'trestle import -f {profile_file} -o imported'.split()
    monkeypatch.setattr(sys, 'argv', test_args)
    rc = Trestle().run()
    assert rc == 0
    # then do a direct read of it and confirm our parameter is there
    profile_path = tmp_trestle_dir / 'profiles/imported/profile.json'
    profile: Profile = Profile.oscal_read(profile_path)
    params = profile.modify.set_parameters
    assert params
    assert len(params) == 1
    assert params[0].param_id == 'my_param'
    assert params[0].depends_on == 'my_depends'
Esempio n. 19
0
def test_validation_unhappy(name, mode, parent, status,
                            tmp_trestle_dir: pathlib.Path,
                            monkeypatch: MonkeyPatch) -> None:
    """Test failure modes of validation."""
    (tmp_trestle_dir / test_utils.CATALOGS_DIR / 'my_test_model').mkdir(
        exist_ok=True, parents=True)
    (tmp_trestle_dir / test_utils.CATALOGS_DIR / 'my_test_model2').mkdir(
        exist_ok=True, parents=True)
    shutil.copyfile(
        test_data_dir / 'json/minimal_catalog_bad_oscal_version.json',
        tmp_trestle_dir / test_utils.CATALOGS_DIR /
        'my_test_model/catalog.json')
    shutil.copyfile(
        test_data_dir / 'json/minimal_catalog.json', tmp_trestle_dir /
        test_utils.CATALOGS_DIR / 'my_test_model2/catalog.json')

    model_def_file = tmp_trestle_dir / test_utils.CATALOGS_DIR / (
        'my_test_model/catalog.json')

    if mode == '-f':
        if not parent:
            testcmd = f'trestle validate {mode} {model_def_file}'
        else:
            testcmd = f'trestle validate {mode} {model_def_file.parent}'
    elif mode == '-n':
        testcmd = f'trestle validate -t catalog -n {name}'
    elif mode == '-x':
        testcmd = f'trestle validate -t catalog -n {name}'
    else:
        testcmd = 'trestle validate -a'

    monkeypatch.setattr(sys, 'argv', testcmd.split())
    rc = Trestle().run()
    assert rc == status
Esempio n. 20
0
def test_abort_safely_on_missing_directory(tmp_trestle_dir: pathlib.Path,
                                           monkeypatch: MonkeyPatch) -> None:
    """Test that validation fails cleanly on a missing directory."""
    task_name = 'tester'
    command_string_setup = f'trestle author headers setup -tn {task_name}'
    command_string_validate_content = f'trestle author headers validate -tn {task_name} -r'
    task_dir = tmp_trestle_dir / task_name

    monkeypatch.setattr(sys, 'argv', command_string_setup.split())
    rc = Trestle().run()
    assert rc == 0
    shutil.rmtree(str(task_dir))

    monkeypatch.setattr(sys, 'argv', command_string_validate_content.split())
    rc = Trestle().run()
    assert rc > 0
Esempio n. 21
0
def test_assemble_not_trestle_root(testdata_dir: pathlib.Path, tmp_trestle_dir: pathlib.Path) -> None:
    """Test execution of assemble from a folder that is not trestle root."""
    os.chdir(pathlib.Path.cwd() / 'catalogs')
    testargs = ['trestle', 'assemble', 'catalog', '-n', 'mycatalog', '-x', 'json']
    with mock.patch.object(sys, 'argv', testargs):
        rc = Trestle().run()
        assert rc == 1
def test_cli(sample_file: str, element_path: str, rc: int,
             testdata_dir: pathlib.Path, monkeypatch: MonkeyPatch) -> None:
    """Test the CLI directly."""
    full_path = testdata_dir / sample_file
    command_str = f'trestle partial-object-validate -f {str(full_path)} -e {element_path}'
    monkeypatch.setattr(sys, 'argv', command_str.split())
    cli_rc = Trestle().run()
    assert rc == cli_rc
Esempio n. 23
0
def test_run_failure_switches(tmp_path, sample_catalog_minimal):
    """Test failure of _run on bad switches for RemoveCmd."""
    # 1. Missing --file argument.
    testargs = ['trestle', 'remove', '-e', 'catalog.metadata.roles']
    with patch.object(sys, 'argv', testargs):
        with pytest.raises(SystemExit) as e:
            Trestle().run()
        assert e.type == SystemExit
        assert e.value.code == 2

    # 2. Missing --element argument.
    testargs = ['trestle', 'remove', '-f', './catalog.json']
    with patch.object(sys, 'argv', testargs):
        with pytest.raises(SystemExit) as e:
            Trestle().run()
        assert e.type == SystemExit
        assert e.value.code == 2
Esempio n. 24
0
def test_assemble_not_trestle_project(tmp_empty_cwd: pathlib.Path) -> None:
    """Test failure if not trestle project."""
    testargs = [
        'trestle', 'assemble', 'catalog', '-n', 'mycatalog', '-x', 'json'
    ]
    with mock.patch.object(sys, 'argv', testargs):
        rc = Trestle().run()
        assert rc == 1
Esempio n. 25
0
def test_run_and_missing_model(tmp_trestle_dir: pathlib.Path) -> None:
    """Test _run and test it fails without top level model file."""
    testargs_root = ['trestle', 'assemble']
    for subcommand in subcommand_list:
        test_args = testargs_root + [subcommand] + ['-n', f'my_{subcommand}'] + ['-x', 'json']
        with mock.patch.object(sys, 'argv', test_args):
            rc = Trestle().run()
            assert rc != 0
def test_for_failure_on_multiple_element_paths(
        testdata_dir: pathlib.Path, monkeypatch: MonkeyPatch) -> None:
    """Test whether a bad element string correctly errors."""
    element_str = "'catalogs,profile'"
    full_path = testdata_dir / 'json/minimal_catalog.json'
    command_str = f'trestle partial-object-validate -f {str(full_path)} -e {element_str}'
    monkeypatch.setattr(sys, 'argv', command_str.split())
    rc = Trestle().run()
    assert rc > 0
def test_missing_file(tmp_path: pathlib.Path,
                      monkeypatch: MonkeyPatch) -> None:
    """Test what happens when a file is missing."""
    fake_catalog_path = tmp_path / 'catalog.json'
    element_str = 'catalog'
    command_str = f'trestle partial-object-validate -f {str(fake_catalog_path)} -e {element_str}'
    monkeypatch.setattr(sys, 'argv', command_str.split())
    rc = Trestle().run()
    assert rc == 1
Esempio n. 28
0
def test_run_failure_switches(tmp_path: pathlib.Path,
                              monkeypatch: MonkeyPatch):
    """Test failure of _run on bad switches for RemoveCmd."""
    # 1. Missing --file argument.
    testargs = ['trestle', 'remove', '-e', 'catalog.metadata.roles']
    monkeypatch.setattr(sys, 'argv', testargs)
    with pytest.raises(SystemExit) as e:
        Trestle().run()
    assert e.type == SystemExit
    assert e.value.code == 2

    # 2. Missing --element argument.
    testargs = ['trestle', 'remove', '-f', './catalog.json']
    monkeypatch.setattr(sys, 'argv', testargs)
    with pytest.raises(SystemExit) as e:
        Trestle().run()
    assert e.type == SystemExit
    assert e.value.code == 2
Esempio n. 29
0
def test_create_cmd(tmp_trestle_dir: pathlib.Path) -> None:
    """Happy path test at the cli level."""
    # Test
    testargs_root = ['trestle', 'create']
    for subcommand in subcommand_list:
        test_args = testargs_root + [subcommand] + ['-n', f'random_named_{subcommand}']
        with mock.patch.object(sys, 'argv', test_args):
            rc = Trestle().run()
            assert rc == 0
Esempio n. 30
0
def test_catalog_generate_failures(tmp_trestle_dir: pathlib.Path,
                                   monkeypatch: MonkeyPatch) -> None:
    """Test failures of author catalog."""
    # disallowed output name
    test_args = 'trestle author catalog-generate -n foo -o profiles'.split()
    monkeypatch.setattr(sys, 'argv', test_args)
    assert Trestle().run() == 1

    # catalog doesn't exist
    test_args = 'trestle author catalog-generate -n foo -o my_md'.split()
    monkeypatch.setattr(sys, 'argv', test_args)
    assert Trestle().run() == 1

    # bad yaml
    bad_yaml_path = str(test_utils.YAML_TEST_DATA_PATH / 'bad_simple.yaml')
    test_args = f'trestle author catalog-generate -n foo -o my_md -y {bad_yaml_path}'.split(
    )
    monkeypatch.setattr(sys, 'argv', test_args)
    assert Trestle().run() == 1