コード例 #1
0
def test_get_snap_project_no_base(snapcraft_yaml, new_dir):
    with pytest.raises(errors.ProjectValidationError) as raised:
        Project.unmarshal(snapcraft_yaml(base=None))

    assert str(raised.value) == (
        "Bad snapcraft.yaml content:\n"
        "- Snap base must be declared when type is not base, kernel or snapd")
コード例 #2
0
ファイル: extensions.py プロジェクト: snapcore/snapcraft
 def run(self, parsed_args):
     snap_project = get_snap_project()
     yaml_data = process_yaml(snap_project.project_file)
     expanded_yaml_data = extensions.apply_extensions(
         yaml_data,
         arch=get_host_architecture(),
         target_arch=get_host_architecture(),
     )
     Project.unmarshal(expanded_yaml_data)
     emit.message(
         yaml.safe_dump(expanded_yaml_data, indent=4, sort_keys=False))
コード例 #3
0
def test_lifecycle_clean_part_names(snapcraft_yaml, project_vars, new_dir, mocker):
    """Clean project inside provider if called with part names."""
    project = Project.unmarshal(snapcraft_yaml(base="core22"))
    run_in_provider_mock = mocker.patch("snapcraft.parts.lifecycle._run_in_provider")

    parts_lifecycle._run_command(
        "clean",
        project=project,
        parse_info={},
        assets_dir=Path(),
        start_time=datetime.now(),
        parallel_build_count=8,
        parsed_args=argparse.Namespace(
            directory=None,
            output=None,
            destructive_mode=False,
            use_lxd=False,
            parts=["part1"],
        ),
    )

    assert run_in_provider_mock.mock_calls == [
        call(
            project,
            "clean",
            argparse.Namespace(
                directory=None,
                output=None,
                destructive_mode=False,
                use_lxd=False,
                parts=["part1"],
            ),
        )
    ]
コード例 #4
0
def test_icon(new_dir):
    content = dedent("""\
            name: project-name
            base: core22
            version: "1.0"
            summary: sanity checks
            description: sanity checks
            grade: stable
            confinement: strict
            icon: foo.png

            parts:
              nil:
                plugin: nil
            """)

    yaml_data = yaml.safe_load(content)
    project = Project.unmarshal(yaml_data)

    # Test without icon raises error
    with pytest.raises(errors.SnapcraftError) as raised:
        run_project_checks(project, assets_dir=Path("snap"))

    assert str(raised.value) == "Specified icon 'foo.png' does not exist."

    # Test with icon passes.
    (new_dir / "foo.png").touch()
    run_project_checks(project, assets_dir=Path("snap"))
コード例 #5
0
def test_lifecycle_debug_shell(snapcraft_yaml, cmd, new_dir, mocker):
    """Adoptable fields shouldn't be empty after adoption."""
    mocker.patch("craft_parts.executor.Executor.execute",
                 side_effect=Exception)
    mock_shell = mocker.patch("subprocess.run")
    project = Project.unmarshal(snapcraft_yaml(base="core22"))

    with pytest.raises(errors.PartsLifecycleError):
        parts_lifecycle._run_command(
            cmd,
            project=project,
            parse_info={},
            assets_dir=Path(),
            start_time=datetime.now(),
            parallel_build_count=8,
            parsed_args=argparse.Namespace(
                directory=None,
                output=None,
                debug=True,
                destructive_mode=True,
                shell=False,
                shell_after=False,
                use_lxd=False,
                parts=["part1"],
            ),
        )

    assert mock_shell.mock_calls == [call(["bash"], check=False, cwd=None)]
コード例 #6
0
def test_lifecycle_run_command_clean(snapcraft_yaml, project_vars, new_dir,
                                     mocker):
    """Clean provider project when called without parts."""
    project = Project.unmarshal(snapcraft_yaml(base="core22"))
    clean_mock = mocker.patch(
        "snapcraft.providers.LXDProvider.clean_project_environments",
        return_value=["instance-name"],
    )

    parts_lifecycle._run_command(
        "clean",
        project=project,
        parse_info={},
        assets_dir=Path(),
        start_time=datetime.now(),
        parallel_build_count=8,
        parsed_args=argparse.Namespace(
            directory=None,
            output=None,
            destructive_mode=False,
            use_lxd=False,
            parts=None,
        ),
    )

    assert clean_mock.mock_calls == [
        call(
            project_name="mytest",
            project_path=new_dir,
            build_on=get_host_architecture(),
            build_for=get_host_architecture(),
        )
    ]
コード例 #7
0
def test_lifecycle_clean_managed(snapcraft_yaml, project_vars, new_dir,
                                 mocker):
    project = Project.unmarshal(snapcraft_yaml(base="core22"))
    run_in_provider_mock = mocker.patch(
        "snapcraft.parts.lifecycle._run_in_provider")
    clean_mock = mocker.patch("snapcraft.parts.PartsLifecycle.clean")
    mocker.patch("snapcraft.utils.is_managed_mode", return_value=True)
    mocker.patch(
        "snapcraft.utils.get_managed_environment_home_path",
        return_value=new_dir / "home",
    )

    parts_lifecycle._run_command(
        "clean",
        project=project,
        parse_info={},
        assets_dir=Path(),
        start_time=datetime.now(),
        parallel_build_count=8,
        parsed_args=argparse.Namespace(
            directory=None,
            output=None,
            destructive_mode=False,
            use_lxd=False,
            parts=["part1"],
        ),
    )

    assert run_in_provider_mock.mock_calls == []
    assert clean_mock.mock_calls == [call(part_names=["part1"])]
コード例 #8
0
def test_accepted_artifacts(new_dir, emitter, snapcraft_yaml):
    project = Project.unmarshal(snapcraft_yaml)
    assets_dir = Path("snap")

    file_assets = [
        ".snapcraft/state",
        "gui/icon.png",
        "gui/other-icon.png",
        "plugins/plugin1.py",
        "plugins/data-file",
        "hooks/configure",
        "hooks/new-hook",
        "keys/key1.asc",
        "keys/key2.asc",
        "local/file",
        "local/dir/file",
    ]

    for file_asset in file_assets:
        asset_path = assets_dir / file_asset
        asset_path.parent.mkdir(parents=True, exist_ok=True)
        asset_path.touch()

    run_project_checks(project, assets_dir=Path("snap"))

    assert emitter.interactions == []
コード例 #9
0
def test_unexpected_things(new_dir, emitter, snapcraft_yaml):
    project = Project.unmarshal(snapcraft_yaml)
    assets_dir = Path("snap")

    file_assets = [
        "dir1/foo",
        "dir1/keys/key1.asc",
        "dir1/keys/key2.asc",
        "dir1/local/dir/file",
        "dir1/local/file",
        "dir1/plugins/data-file",
        "dir1/plugins/plugin1.py",
        "dir2/foo",
        "dir2/hooks/configure",
        "dir2/hooks/new-hook",
        "gui/icon.jpg",
    ]

    for file_asset in file_assets:
        asset_path = assets_dir / file_asset
        asset_path.parent.mkdir(parents=True, exist_ok=True)
        asset_path.touch()

    run_project_checks(project, assets_dir=Path("snap"))
    assert emitter.assert_progress(
        "The 'snap' directory is meant specifically for snapcraft, but it contains\n"
        "the following non-snapcraft-related paths:\n"
        "- dir1\n"
        "- dir1/foo\n"
        "- dir1/keys\n"
        "- dir1/keys/key1.asc\n"
        "- dir1/keys/key2.asc\n"
        "- dir1/local\n"
        "- dir1/local/dir\n"
        "- dir1/local/dir/file\n"
        "- dir1/local/file\n"
        "- dir1/plugins\n"
        "- dir1/plugins/data-file\n"
        "- dir1/plugins/plugin1.py\n"
        "- dir2\n"
        "- dir2/foo\n"
        "- dir2/hooks\n"
        "- dir2/hooks/configure\n"
        "- dir2/hooks/new-hook\n"
        "- gui/icon.jpg\n"
        "\n"
        "This is unsupported and may cause unexpected behavior. If you must store\n"
        "these files within the 'snap' directory, move them to 'snap/local'\n"
        "which is ignored by snapcraft.",
        permanent=True,
    )
コード例 #10
0
def test_lifecycle_pack_managed(cmd, snapcraft_yaml, project_vars, new_dir,
                                mocker):
    project = Project.unmarshal(snapcraft_yaml(base="core22"))
    run_in_provider_mock = mocker.patch(
        "snapcraft.parts.lifecycle._run_in_provider")
    run_mock = mocker.patch("snapcraft.parts.PartsLifecycle.run")
    pack_mock = mocker.patch("snapcraft.pack.pack_snap")
    mocker.patch("snapcraft.meta.snap_yaml.write")
    mocker.patch("snapcraft.utils.is_managed_mode", return_value=True)
    mocker.patch(
        "snapcraft.utils.get_managed_environment_home_path",
        return_value=new_dir / "home",
    )

    parts_lifecycle._run_command(
        cmd,
        project=project,
        parse_info={},
        assets_dir=Path(),
        start_time=datetime.now(),
        parallel_build_count=8,
        parsed_args=argparse.Namespace(
            directory=None,
            output=None,
            debug=False,
            bind_ssh=False,
            enable_manifest=False,
            manifest_image_information=None,
            destructive_mode=False,
            shell=False,
            shell_after=False,
            use_lxd=False,
            parts=[],
        ),
    )

    assert run_in_provider_mock.mock_calls == []
    assert run_mock.mock_calls == [
        call("prime", debug=False, shell=False, shell_after=False)
    ]
    assert pack_mock.mock_calls[:1] == [
        call(
            new_dir / "home/prime",
            output=None,
            compression="xz",
            name="mytest",
            version="0.1",
            target_arch=get_host_architecture(),
        )
    ]
コード例 #11
0
    def test_setup_assets_remote_icon(self, desktop_file, yaml_data, new_dir):
        # create primed tree (no icon)
        desktop_file("prime/test.desktop")

        # define project
        # pylint: disable=line-too-long
        project = Project.unmarshal(
            yaml_data(
                {
                    "adopt-info": "part",
                    "icon":
                    "https://dashboard.snapcraft.io/site_media/appmedia/2018/04/Snapcraft-logo-bird.png",
                    "apps": {
                        "app1": {
                            "command": "test.sh",
                            "common-id": "my-test",
                            "desktop": "test.desktop",
                        },
                    },
                }, ))
        # pylint: enable=line-too-long

        setup_assets(
            project,
            assets_dir=Path("snap"),
            project_dir=Path.cwd(),
            prime_dir=Path("prime"),
        )

        # desktop file should be in meta/gui and named after app
        desktop_path = Path("prime/meta/gui/app1.desktop")
        assert desktop_path.is_file()

        # desktop file content should make icon relative to ${SNAP}
        content = desktop_path.read_text()
        assert content == textwrap.dedent("""\
            [Desktop Entry]
            Name=appstream-desktop
            Exec=test-project.app1
            Type=Application
            Icon=${SNAP}/meta/gui/icon.png

            """)

        # icon was downloaded
        icon_path = Path("prime/meta/gui/icon.png")
        assert icon_path.is_file()
        assert icon_path.stat().st_size > 0
コード例 #12
0
ファイル: lifecycle.py プロジェクト: snapcore/snapcraft
def run(command_name: str, parsed_args: "argparse.Namespace") -> None:
    """Run the parts lifecycle.

    :raises SnapcraftError: if the step name is invalid, or the project
        yaml file cannot be loaded.
    :raises LegacyFallback: if the project's base is not core22.
    """
    emit.debug(f"command: {command_name}, arguments: {parsed_args}")

    snap_project = get_snap_project()
    yaml_data = process_yaml(snap_project.project_file)
    start_time = datetime.now()
    build_plan = get_build_plan(yaml_data, parsed_args)

    if parsed_args.provider:
        raise errors.SnapcraftError("Option --provider is not supported.")

    # Register our own plugins and callbacks
    plugins.register()
    callbacks.register_prologue(_set_global_environment)
    callbacks.register_pre_step(_set_step_environment)

    build_count = utils.get_parallel_build_count()

    for build_on, build_for in build_plan:
        emit.verbose(f"Running on {build_on} for {build_for}")
        yaml_data_for_arch = apply_yaml(yaml_data, build_on, build_for)
        parse_info = _extract_parse_info(yaml_data_for_arch)
        _expand_environment(
            yaml_data_for_arch,
            parallel_build_count=build_count,
            target_arch=build_for,
        )
        project = Project.unmarshal(yaml_data_for_arch)

        try:
            _run_command(
                command_name,
                project=project,
                parse_info=parse_info,
                parallel_build_count=build_count,
                assets_dir=snap_project.assets_dir,
                start_time=start_time,
                parsed_args=parsed_args,
            )
        except PermissionError as err:
            raise errors.FilePermissionError(err.filename, reason=err.strerror)
コード例 #13
0
def test_snapcraft_yaml_load(new_dir, snapcraft_yaml, filename, mocker):
    """Snapcraft.yaml should be parsed as a valid yaml file."""
    yaml_data = snapcraft_yaml(base="core22", filename=filename)
    run_command_mock = mocker.patch("snapcraft.parts.lifecycle._run_command")
    mocker.patch("snapcraft.utils.get_parallel_build_count", return_value=5)

    parts_lifecycle.run(
        "pull",
        argparse.Namespace(
            parts=["part1"],
            destructive_mode=True,
            use_lxd=False,
            provider=None,
            enable_manifest=False,
            manifest_image_information=None,
            bind_ssh=False,
            build_for=None,
        ),
    )

    project = Project.unmarshal(yaml_data)

    if filename == "build-aux/snap/snapcraft.yaml":
        assets_dir = Path("build-aux/snap")
    else:
        assets_dir = Path("snap")

    assert run_command_mock.mock_calls == [
        call(
            "pull",
            project=project,
            parse_info={},
            assets_dir=assets_dir,
            parallel_build_count=5,
            start_time=mocker.ANY,
            parsed_args=argparse.Namespace(
                parts=["part1"],
                destructive_mode=True,
                use_lxd=False,
                provider=None,
                enable_manifest=False,
                manifest_image_information=None,
                bind_ssh=False,
                build_for=None,
            ),
        ),
    ]
コード例 #14
0
def test_lifecycle_metadata_empty(field, snapcraft_yaml, new_dir):
    """Adoptable fields shouldn't be empty after adoption."""
    yaml_data = snapcraft_yaml(base="core22")
    yaml_data.pop(field)
    yaml_data["adopt-info"] = "part"
    project = Project.unmarshal(yaml_data)

    with pytest.raises(errors.SnapcraftError) as raised:
        update_project_metadata(
            project,
            project_vars={"version": "", "grade": ""},
            metadata_list=[],
            assets_dir=new_dir,
            prime_dir=new_dir,
        )

    assert str(raised.value) == f"Field {field!r} was not adopted from metadata"
コード例 #15
0
def test_lifecycle_pack_metadata_error(cmd, snapcraft_yaml, new_dir, mocker):
    project = Project.unmarshal(snapcraft_yaml(base="core22"))
    run_mock = mocker.patch("snapcraft.parts.PartsLifecycle.run")
    mocker.patch("snapcraft.utils.is_managed_mode", return_value=True)
    mocker.patch(
        "snapcraft.utils.get_managed_environment_home_path",
        return_value=new_dir / "home",
    )
    mocker.patch(
        "snapcraft.parts.PartsLifecycle.project_vars",
        new_callable=PropertyMock,
        return_value={
            "version": "0.1",
            "grade": "invalid"
        },  # invalid value
    )
    pack_mock = mocker.patch("snapcraft.pack.pack_snap")
    mocker.patch("snapcraft.meta.snap_yaml.write")

    with pytest.raises(errors.SnapcraftError) as raised:
        parts_lifecycle._run_command(
            cmd,
            project=project,
            assets_dir=Path(),
            start_time=datetime.now(),
            parse_info={},
            parallel_build_count=8,
            parsed_args=argparse.Namespace(
                directory=None,
                output=None,
                debug=False,
                destructive_mode=False,
                shell=False,
                shell_after=False,
                use_lxd=False,
                parts=[],
            ),
        )

    assert str(raised.value) == (
        "error setting grade: unexpected value; permitted: 'stable', 'devel'")
    assert run_mock.mock_calls == [
        call("prime", debug=False, shell=False, shell_after=False)
    ]
    assert pack_mock.mock_calls == []
コード例 #16
0
    def test_setup_assets_no_apps(self, desktop_file, yaml_data, new_dir):
        desktop_file("prime/test.desktop")
        Path("prime/usr/share/icons").mkdir(parents=True)
        Path("prime/usr/share/icons/icon.svg").touch()
        Path("snap/gui").mkdir()

        # define project
        project = Project.unmarshal(yaml_data({"adopt-info": "part"}))

        # setting up assets does not crash
        setup_assets(
            project,
            assets_dir=Path("snap"),
            project_dir=Path.cwd(),
            prime_dir=Path("prime"),
        )

        assert os.listdir("prime/meta/gui") == []
コード例 #17
0
def test_gadget_missing(yaml_data, new_dir):
    project = Project.unmarshal(
        yaml_data({
            "type": "gadget",
            "version": "1.0",
            "summary": "summary",
            "description": "description",
        }))

    with pytest.raises(errors.SnapcraftError) as raised:
        setup_assets(
            project,
            assets_dir=Path("snap"),
            project_dir=Path.cwd(),
            prime_dir=Path("prime"),
        )

    assert str(raised.value) == "gadget.yaml is required for gadget snaps"
コード例 #18
0
def test_lifecycle_adopt_project_vars(snapcraft_yaml, new_dir):
    """Adoptable fields shouldn't be empty after adoption."""
    yaml_data = snapcraft_yaml(base="core22")
    yaml_data.pop("version")
    yaml_data.pop("grade")
    yaml_data["adopt-info"] = "part"
    project = Project.unmarshal(yaml_data)

    update_project_metadata(
        project,
        project_vars={"version": "42", "grade": "devel"},
        metadata_list=[],
        assets_dir=new_dir,
        prime_dir=new_dir,
    )

    assert project.version == "42"
    assert project.grade == "devel"
コード例 #19
0
    def test_setup_assets_icon_in_assets_dir(self, desktop_file, yaml_data,
                                             new_dir):
        desktop_file("prime/test.desktop")
        Path("snap/gui").mkdir(parents=True)
        Path("snap/gui/icon.svg").touch()

        # define project
        project = Project.unmarshal(
            yaml_data(
                {
                    "adopt-info": "part",
                    "apps": {
                        "app1": {
                            "command": "test.sh",
                            "common-id": "my-test",
                            "desktop": "test.desktop",
                        },
                    },
                }, ))

        setup_assets(
            project,
            assets_dir=Path("snap"),
            project_dir=Path.cwd(),
            prime_dir=Path("prime"),
        )

        # desktop file should be in meta/gui and named after app
        desktop_path = Path("prime/meta/gui/app1.desktop")
        assert desktop_path.is_file()

        # desktop file content should make icon relative to ${SNAP}
        content = desktop_path.read_text()
        assert content == textwrap.dedent("""\
            [Desktop Entry]
            Name=appstream-desktop
            Exec=test-project.app1
            Type=Application
            Icon=${SNAP}/snap/gui/icon.svg

            """)

        # icon file exists
        Path("prime/snap/gui/icon.svg").is_file()
コード例 #20
0
def test_gadget(yaml_data, gadget_yaml_file, new_dir):
    project = Project.unmarshal(
        yaml_data({
            "type": "gadget",
            "version": "1.0",
            "summary": "summary",
            "description": "description",
        }))

    setup_assets(
        project,
        assets_dir=Path("snap"),
        project_dir=Path.cwd(),
        prime_dir=Path("prime"),
    )

    # gadget file should be in meta/
    gadget_path = Path("prime/meta/gadget.yaml")
    assert gadget_path.is_file()
コード例 #21
0
def test_update_project_metadata(project_yaml_data, appstream_file, new_dir):
    project = Project.unmarshal(project_yaml_data({"adopt-info": "part"}))
    metadata = ExtractedMetadata(
        common_id="common.id",
        title="title",
        summary="summary",
        description="description",
        version="1.2.3",
        icon="assets/icon.png",
        desktop_file_paths=["assets/file.desktop"],
    )
    assets_dir = Path("assets")
    prime_dir = Path("prime")

    # set up project apps
    project.apps = {
        "app1": _project_app({"command": "bin/app1"}),
        "app2": _project_app({"command": "bin/app2", "common_id": "other.id"}),
        "app3": _project_app({"command": "bin/app3", "common_id": "common.id"}),
    }

    prime_dir.mkdir()
    (prime_dir / "assets").mkdir()
    (prime_dir / "assets/icon.png").touch()
    (prime_dir / "assets/file.desktop").touch()

    prj_vars = {"version": "0.1", "grade": "stable"}
    update_project_metadata(
        project,
        project_vars=prj_vars,
        metadata_list=[metadata],
        assets_dir=assets_dir,
        prime_dir=prime_dir,
    )

    assert project.title == "title"
    assert project.summary == "summary"  # already set in project
    assert project.description == "description"  # already set in project
    assert project.version == "0.1"  # already set in project
    assert project.icon == "assets/icon.png"
    assert project.apps["app3"].desktop == "assets/file.desktop"
コード例 #22
0
def test_lifecycle_shell_after(snapcraft_yaml, cmd, new_dir, mocker):
    """Adoptable fields shouldn't be empty after adoption."""
    last_step = None

    def _fake_execute(_, action: Action, **kwargs):  # pylint: disable=unused-argument
        nonlocal last_step
        last_step = action.step

    mocker.patch("craft_parts.executor.Executor.execute", new=_fake_execute)
    mock_shell = mocker.patch("subprocess.run")
    project = Project.unmarshal(snapcraft_yaml(base="core22"))

    parts_lifecycle._run_command(
        cmd,
        project=project,
        parse_info={},
        assets_dir=Path(),
        start_time=datetime.now(),
        parallel_build_count=8,
        parsed_args=argparse.Namespace(
            directory=None,
            output=None,
            debug=False,
            destructive_mode=True,
            shell=False,
            shell_after=True,
            use_lxd=False,
            parts=["part1"],
        ),
    )

    expected_last_step = Step.PULL
    if cmd == "build":
        expected_last_step = Step.BUILD
    if cmd == "stage":
        expected_last_step = Step.STAGE
    if cmd == "prime":
        expected_last_step = Step.PRIME

    assert last_step == expected_last_step
    assert mock_shell.mock_calls == [call(["bash"], check=False, cwd=None)]
コード例 #23
0
 def _simple_project(**kwargs):
     snapcraft_config = {
         "name": "mytest",
         "version": "1.29.3",
         "base": "core22",
         "summary": "Single-line elevator pitch for your amazing snap",
         "description": "test-description",
         "confinement": "strict",
         "parts": {
             "part1": {
                 "plugin": "nil",
             },
         },
         "apps": {
             "app1": {
                 "command": "bin/mytest",
             },
         },
         **kwargs,
     }
     return Project.unmarshal(snapcraft_config)
コード例 #24
0
def test_kernel_missing(yaml_data, new_dir):
    project = Project.unmarshal({
        "name": "custom-kernel",
        "type": "kernel",
        "confinement": "strict",
        "version": "1.0",
        "summary": "summary",
        "description": "description",
        "parts": {},
    })

    setup_assets(
        project,
        assets_dir=Path("snap"),
        project_dir=Path.cwd(),
        prime_dir=Path("prime"),
    )

    # kernel file should not be in meta/
    kernel_path = Path("prime/meta/kernel.yaml")
    assert not kernel_path.is_file()
コード例 #25
0
def test_lifecycle_run_command_pack(cmd, snapcraft_yaml, project_vars, new_dir, mocker):
    project = Project.unmarshal(snapcraft_yaml(base="core22"))
    run_mock = mocker.patch("snapcraft.parts.PartsLifecycle.run")
    pack_mock = mocker.patch("snapcraft.pack.pack_snap")

    parts_lifecycle._run_command(
        cmd,
        project=project,
        parse_info={},
        assets_dir=Path(),
        start_time=datetime.now(),
        parallel_build_count=8,
        parsed_args=argparse.Namespace(
            directory=None,
            output=None,
            debug=False,
            destructive_mode=True,
            enable_manifest=False,
            shell=False,
            shell_after=False,
            use_lxd=False,
            parts=[],
        ),
    )

    assert run_mock.mock_calls == [
        call("prime", debug=False, shell=False, shell_after=False)
    ]
    assert pack_mock.mock_calls[:1] == [
        call(
            new_dir / "prime",
            output=None,
            compression="xz",
            name="mytest",
            version="0.1",
            target_arch=get_host_architecture(),
        )
    ]
コード例 #26
0
def test_lifecycle_clean_destructive_mode(snapcraft_yaml, project_vars,
                                          new_dir, mocker):
    """Clean local project if called in destructive mode."""
    project = Project.unmarshal(snapcraft_yaml(base="core22"))
    clean_mock = mocker.patch("snapcraft.parts.PartsLifecycle.clean")

    parts_lifecycle._run_command(
        "clean",
        project=project,
        parse_info={},
        assets_dir=Path(),
        start_time=datetime.now(),
        parallel_build_count=8,
        parsed_args=argparse.Namespace(
            directory=None,
            output=None,
            destructive_mode=True,
            use_lxd=False,
            parts=None,
        ),
    )

    assert clean_mock.mock_calls == [call(part_names=None)]
コード例 #27
0
def test_lifecycle_run_command_step(
    cmd, step, debug_shell, snapcraft_yaml, project_vars, new_dir, mocker
):
    project = Project.unmarshal(snapcraft_yaml(base="core22"))
    run_mock = mocker.patch("snapcraft.parts.PartsLifecycle.run")
    mocker.patch("snapcraft.meta.snap_yaml.write")
    pack_mock = mocker.patch("snapcraft.pack.pack_snap")

    parsed_args = argparse.Namespace(
        debug=False,
        destructive_mode=True,
        enable_manifest=False,
        shell=False,
        shell_after=False,
        use_lxd=False,
        parts=[],
    )

    if debug_shell:
        setattr(parsed_args, debug_shell, True)

    parts_lifecycle._run_command(
        cmd,
        project=project,
        parse_info={},
        assets_dir=Path(),
        start_time=datetime.now(),
        parallel_build_count=8,
        parsed_args=parsed_args,
    )

    call_args = {"debug": False, "shell": False, "shell_after": False}
    if debug_shell:
        call_args[debug_shell] = True

    assert run_mock.mock_calls == [call(step, **call_args)]
    assert pack_mock.mock_calls == []
コード例 #28
0
def test_lifecycle_pack_not_managed(cmd, snapcraft_yaml, new_dir, mocker):
    project = Project.unmarshal(snapcraft_yaml(base="core22"))
    run_in_provider_mock = mocker.patch(
        "snapcraft.parts.lifecycle._run_in_provider")
    run_mock = mocker.patch("snapcraft.parts.PartsLifecycle.run")
    mocker.patch("snapcraft.utils.is_managed_mode", return_value=False)

    parts_lifecycle._run_command(
        cmd,
        project=project,
        parse_info={},
        assets_dir=Path(),
        start_time=datetime.now(),
        parallel_build_count=8,
        parsed_args=argparse.Namespace(
            directory=None,
            output=None,
            destructive_mode=False,
            use_lxd=False,
            parts=[],
        ),
    )

    assert run_mock.mock_calls == []
    assert run_in_provider_mock.mock_calls == [
        call(
            project,
            cmd,
            argparse.Namespace(
                directory=None,
                output=None,
                destructive_mode=False,
                use_lxd=False,
                parts=[],
            ),
        )
    ]
コード例 #29
0
    def test_setup_assets_hook_command_chain_error(self, yaml_data, new_dir):
        # define project
        project = Project.unmarshal(
            yaml_data(
                {
                    "adopt-info": "part1",
                    "hooks": {
                        "hook1": {
                            "command-chain": ["does-not-exist"]
                        },
                    },
                }, ))

        with pytest.raises(errors.SnapcraftError) as raised:
            setup_assets(
                project,
                assets_dir=Path("snap"),
                project_dir=Path.cwd(),
                prime_dir=new_dir,
            )

        assert str(raised.value) == (
            "Failed to generate snap metadata: The command-chain item 'does-not-exist' "
            "defined in hook 'hook1' does not exist or is not executable.")
コード例 #30
0
def complex_project():
    snapcraft_yaml = textwrap.dedent("""\
        name: mytest
        version: 1.29.3
        base: core22
        type: app
        summary: Single-line elevator pitch for your amazing snap
        description: |
          This is my-snap's description. You have a paragraph or two to tell the
          most important story about your snap. Keep it under 100 words though,
          we live in tweetspace and your description wants to look good in the snap
          store.

        grade: devel
        confinement: strict

        environment:
          GLOBAL_VARIABLE: test-global-variable

        parts:
          part1:
            plugin: nil

        apps:
          app1:
            command: bin/mytest
            autostart: test-app.desktop
            common-id: test-common-id
            bus-name: test-bus-name
            completer: test-completer
            stop-command: test-stop-command
            post-stop-command: test-post-stop-command
            start-timeout: 1s
            stop-timeout: 2s
            watchdog-timeout: 3s
            reload-command: test-reload-command
            restart-delay: 4s
            timer: test-timer
            daemon: simple
            after: [test-after-1, test-after-2]
            before: [test-before-1, test-before-2]
            refresh-mode: endure
            stop-mode: sigterm
            restart-condition: on-success
            install-mode: enable
            aliases: [test-alias-1, test-alias-2]
            environment:
              APP_VARIABLE: test-app-variable
            command-chain:
            - cc-test1
            - cc-test2
            sockets:
              test-socket-1:
                listen-stream: /tmp/test-socket.sock
                socket-mode: 0
              test-socket-2:
                listen-stream: 100
                socket-mode: 1

        plugs:
          empty-plug:
          string-plug: home
          dict-plug:
            string-parameter: foo
            bool-parameter: True
          content-interface:
            interface: content
            target: test-target
            content: test-content
            default-provider: test-provider

        slots:
          empty-slot:
          string-slot: slot
          dict-slot:
            string-parameter: foo
            bool-parameter: True
          content-interface:
            interface: content
            read:
              - /

        hooks:
          configure:
            command-chain: ["test"]
            environment:
              test-variable-1: "test"
              test-variable-2: "test"
            plugs:
              - home
              - network
          install:
            environment:
              environment-var-1: "test"

        system-usernames:
          snap_daemon:
            scope: shared
          snap_microk8s: shared

        layout:
          /usr/share/libdrm:
            bind: $SNAP/gnome-platform/usr/share/libdrm
          /usr/lib/x86_64-linux-gnu/webkit2gtk-4.0:
            bind: $SNAP/gnome-platform/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0
          /usr/share/xml/iso-codes:
            bind: $SNAP/gnome-platform/usr/share/xml/iso-codes
        """)
    data = yaml.safe_load(snapcraft_yaml)
    yield Project.unmarshal(data)