Exemple #1
0
    def test_launch_for_type_base(self):
        self.project.info.name = "core18"
        self.project.info.type = "base"
        self.project.info.base = None

        instance = Multipass(project=self.project, echoer=self.echoer_mock)
        self.useFixture(
            fixtures.MockPatchObject(
                instance,
                "_get_instance_info",
                side_effect=[
                    errors.ProviderInfoError(
                        provider_name="multipass", exit_code=1, stderr=b"error"
                    ),
                    {},
                ],
            )
        )

        instance.create()

        self.multipass_cmd_mock().launch.assert_called_once_with(
            instance_name="snapcraft-core18",
            cpus="2",
            mem="2G",
            disk="256G",
            image="snapcraft:core18",
            cloud_init=mock.ANY,
        )
Exemple #2
0
    def test_provision_project(self):
        multipass = Multipass(project=self.project, echoer=self.echoer_mock)

        # In the real world, MultipassCommand would return an error when
        # calling this on an instance that does not exist.
        multipass.provision_project("source.tar")

        self.multipass_cmd_mock().execute.assert_has_calls([
            mock.call(
                instance_name=self.instance_name,
                command=["sudo", "-i", "mkdir", "~/project"],
            ),
            mock.call(
                instance_name=self.instance_name,
                command=[
                    "sudo",
                    "-i",
                    "tar",
                    "-xvf",
                    "source.tar",
                    "-C",
                    "~/project",
                ],
            ),
        ])
        self.multipass_cmd_mock().copy_files.assert_called_once_with(
            destination="{}:source.tar".format(self.instance_name),
            source="source.tar")

        self.multipass_cmd_mock().launch.assert_not_called()
        self.multipass_cmd_mock().info.assert_not_called()
        self.multipass_cmd_mock().stop.assert_not_called()
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #3
0
    def test_pull_file(self):
        multipass = Multipass(project=self.project, echoer=self.echoer_mock)

        multipass.pull_file("src.txt", "dest.txt")

        self.multipass_cmd_mock().execute.assert_called_once_with(
            command=[
                "sudo",
                "-i",
                "env",
                "SNAPCRAFT_HAS_TTY=False",
                "test",
                "-f",
                "src.txt",
            ],
            hide_output=False,
            instance_name="snapcraft-project-name",
        )

        self.multipass_cmd_mock().copy_files.assert_called_once_with(
            destination="dest.txt", source="{}:src.txt".format(self.instance_name)
        )

        self.multipass_cmd_mock().info.assert_not_called()
        self.multipass_cmd_mock().stop.assert_not_called()
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #4
0
    def test_provision_project(self):
        multipass = Multipass(project=self.project, echoer=self.echoer_mock)

        # In the real world, MultipassCommand would return an error when
        # calling this on an instance that does not exist.
        multipass.provision_project("source.tar")

        self.multipass_cmd_mock().execute.assert_has_calls(
            [
                mock.call(
                    instance_name=self.instance_name, command=["mkdir", "project-name"]
                ),
                mock.call(
                    instance_name=self.instance_name,
                    command=["tar", "-xvf", "source.tar", "-C", "project-name"],
                ),
            ]
        )
        self.multipass_cmd_mock().copy_files.assert_called_once_with(
            destination="{}:source.tar".format(self.instance_name), source="source.tar"
        )

        self.multipass_cmd_mock().launch.assert_not_called()
        self.multipass_cmd_mock().info.assert_not_called()
        self.multipass_cmd_mock().stop.assert_not_called()
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #5
0
    def test_instance_does_not_exist_on_destroy(self):
        # An error is raised if the queried image does not exist
        self.multipass_cmd_mock().info.side_effect = errors.ProviderInfoError(
            provider_name=self.instance_name, exit_code=2)

        multipass = Multipass(project=self.project, echoer=self.echoer_mock)

        multipass.destroy()

        self.multipass_cmd_mock().stop.assert_not_called()
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #6
0
    def test_instance_does_not_exist_on_destroy(self):
        # An error is raised if the queried image does not exist
        self.multipass_cmd_mock().info.side_effect = errors.ProviderInfoError(
            provider_name=self.instance_name, exit_code=2
        )

        multipass = Multipass(project=self.project, echoer=self.echoer_mock)

        multipass.destroy()

        self.multipass_cmd_mock().stop.assert_not_called()
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #7
0
    def test_destroy_instance_with_stop_delay_invalid(self):
        self.useFixture(
            fixtures.EnvironmentVariable(
                "SNAPCRAFT_BUILD_ENVIRONMENT_STOP_TIME", "A"))

        multipass = Multipass(project=self.project, echoer=self.echoer_mock)

        multipass.create()

        self.assertRaises(SnapcraftEnvironmentError, multipass.destroy)

        self.multipass_cmd_mock().stop.assert_not_called()
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #8
0
    def test_launch_with_disk_from_environment(self):
        self.useFixture(
            fixtures.EnvironmentVariable("SNAPCRAFT_BUILD_ENVIRONMENT_DISK",
                                         "400G"))

        instance = Multipass(project=self.project, echoer=self.echoer_mock)
        instance.create()

        self.multipass_cmd_mock().launch.assert_called_once_with(
            instance_name=self.instance_name,
            cpus="2",
            mem="2G",
            disk="400G",
            image="snapcraft:core16",
        )
Exemple #9
0
    def test_pull_file(self):
        multipass = Multipass(project=self.project, echoer=self.echoer_mock)

        multipass.pull_file("src.txt", "dest.txt")

        self.multipass_cmd_mock().execute.assert_called_once_with(
            command=["test", "-f", "src.txt"],
            instance_name="snapcraft-project-name")

        self.multipass_cmd_mock().copy_files.assert_called_once_with(
            destination="dest.txt",
            source="{}:src.txt".format(self.instance_name))

        self.multipass_cmd_mock().info.assert_not_called()
        self.multipass_cmd_mock().stop.assert_not_called()
        self.multipass_cmd_mock().delete.assert_not_called()
    def test_launch_with_ram_from_environment(self):
        self.useFixture(
            fixtures.EnvironmentVariable("SNAPCRAFT_BUILD_ENVIRONMENT_MEMORY",
                                         "4G"))

        instance = Multipass(project=self.project, echoer=self.echoer_mock)
        instance.create()

        self.multipass_cmd_mock().launch.assert_called_once_with(
            instance_name=self.instance_name,
            cpus=mock.ANY,
            mem="4G",
            disk="256G",
            image="16.04",
            cloud_init=mock.ANY,
        )
Exemple #11
0
    def test_retrieve_snap(self):
        multipass = Multipass(project=self.project, echoer=self.echoer_mock)

        # In the real world, MultipassCommand would return an error when
        # calling this on an instance that does not exist.
        multipass.retrieve_snap()

        self.multipass_cmd_mock().copy_files.assert_called_once_with(
            destination='project-name_{}.snap'.format(self.project.deb_arch),
            source='{}:project-name/project-name_{}.snap'.format(
                self.instance_name, self.project.deb_arch))

        self.multipass_cmd_mock().execute.assert_not_called()
        self.multipass_cmd_mock().launch.assert_not_called()
        self.multipass_cmd_mock().info.assert_not_called()
        self.multipass_cmd_mock().stop.assert_not_called()
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #12
0
    def test_lifecycle(self):
        with Multipass(project=self.project,
                       echoer=self.echoer_mock,
                       is_ephemeral=False) as instance:
            instance.mount_project()
            instance.execute_step(steps.PULL)

        self.multipass_cmd_mock().launch.assert_called_once_with(
            instance_name=self.instance_name,
            cpus="2",
            mem="2G",
            disk="256G",
            image=self.expected_image,
            cloud_init=mock.ANY,
        )
        self.multipass_cmd_mock().execute.assert_has_calls([
            mock.call(
                instance_name=self.instance_name,
                hide_output=True,
                command=[
                    "sudo",
                    "-i",
                    "env",
                    "SNAPCRAFT_HAS_TTY=False",
                    "printenv",
                    "HOME",
                ],
            ),
            mock.call(
                instance_name=self.instance_name,
                hide_output=False,
                command=[
                    "sudo",
                    "-i",
                    "env",
                    "SNAPCRAFT_HAS_TTY=False",
                    "snapcraft",
                    "pull",
                ],
            ),
        ])
        self.multipass_cmd_mock().mount.assert_called_once_with(
            source=mock.ANY,
            target="{}:{}".format(self.instance_name, "/root/project"),
            uid_map=self.expected_uid_map,
            gid_map=self.expected_gid_map,
        )
        self.multipass_cmd_mock().umount.assert_not_called()
        self.assertThat(self.multipass_cmd_mock().info.call_count, Equals(3))
        self.multipass_cmd_mock().info.assert_has_calls([
            mock.call(instance_name=self.instance_name, output_format="json"),
            mock.call(instance_name=self.instance_name, output_format="json"),
        ])
        self.multipass_cmd_mock().copy_files.assert_not_called()
        self.multipass_cmd_mock().stop.assert_called_once_with(
            instance_name=self.instance_name, time=10)
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #13
0
    def test_launch_with_disk_from_environment(self):
        self.useFixture(
            fixtures.EnvironmentVariable("SNAPCRAFT_BUILD_ENVIRONMENT_DISK", "400G")
        )
        self.multipass_cmd_mock().start.side_effect = errors.ProviderStartError(
            provider_name="multipass", exit_code=1
        )

        instance = Multipass(project=self.project, echoer=self.echoer_mock)
        instance.create()

        self.multipass_cmd_mock().launch.assert_called_once_with(
            instance_name=self.instance_name,
            mem="2G",
            disk="400G",
            image="16.04",
            cloud_init=mock.ANY,
        )
    def test_ephemeral_instance_with_contextmanager(self):
        with Multipass(project=self.project,
                       echoer=self.echoer_mock,
                       is_ephemeral=True) as instance:
            instance.provision_project("source.tar")
            instance.build_project()
            instance.retrieve_snap()

        self.multipass_cmd_mock().launch.assert_called_once_with(
            instance_name=self.instance_name,
            cpus=mock.ANY,
            mem="2G",
            disk="256G",
            image="16.04",
            cloud_init=mock.ANY,
        )
        # Given SnapInjector is mocked, we only need to verify the commands
        # called from the Multipass class.
        self.multipass_cmd_mock().execute.assert_has_calls([
            mock.call(instance_name=self.instance_name,
                      command=["mkdir", "~/project"]),
            mock.call(
                instance_name=self.instance_name,
                command=["tar", "-xvf", "source.tar", "-C", "~/project"],
            ),
            mock.call(
                instance_name=self.instance_name,
                command=[
                    "snapcraft",
                    "snap",
                    "--output",
                    "project-name_{}.snap".format(self.project.deb_arch),
                ],
            ),
        ])
        self.assertThat(self.multipass_cmd_mock().info.call_count, Equals(2))
        self.multipass_cmd_mock().info.assert_has_calls([
            mock.call(instance_name=self.instance_name, output_format="json"),
            mock.call(instance_name=self.instance_name, output_format="json"),
        ])

        self.multipass_cmd_mock().copy_files.assert_has_calls([
            mock.call(
                destination="{}:source.tar".format(self.instance_name),
                source="source.tar",
            ),
            mock.call(
                destination="project-name_{}.snap".format(
                    self.project.deb_arch),
                source="{}:~/project/project-name_{}.snap".format(
                    self.instance_name, self.project.deb_arch),
            ),
        ])
        self.multipass_cmd_mock().stop.assert_called_once_with(
            instance_name=self.instance_name)
        self.multipass_cmd_mock().delete.assert_called_once_with(
            instance_name=self.instance_name, purge=True)
Exemple #15
0
    def test_retrieve_snap(self):
        multipass = Multipass(project=self.project, echoer=self.echoer_mock)

        # In the real world, MultipassCommand would return an error when
        # calling this on an instance that does not exist.
        multipass.retrieve_snap()

        self.multipass_cmd_mock().copy_files.assert_called_once_with(
            destination="project-name_{}.snap".format(self.project.deb_arch),
            source="{}:project-name/project-name_{}.snap".format(
                self.instance_name, self.project.deb_arch
            ),
        )

        self.multipass_cmd_mock().execute.assert_not_called()
        self.multipass_cmd_mock().launch.assert_not_called()
        self.multipass_cmd_mock().info.assert_not_called()
        self.multipass_cmd_mock().stop.assert_not_called()
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #16
0
    def test_build_project(self):
        multipass = Multipass(project=self.project, echoer=self.echoer_mock)

        # In the real world, MultipassCommand would return an error when
        # calling this on an instance that does not exist.
        multipass.build_project()

        self.multipass_cmd_mock().execute.assert_called_once_with(
            instance_name=self.instance_name,
            command=[
                'sh', '-c', 'cd project-name; /snap/bin/snapcraft '
                'snap --output project-name_{}.snap'.format(
                    self.project.deb_arch)
            ])

        self.multipass_cmd_mock().copy_files.assert_not_called()
        self.multipass_cmd_mock().launch.assert_not_called()
        self.multipass_cmd_mock().info.assert_not_called()
        self.multipass_cmd_mock().stop.assert_not_called()
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #17
0
    def test_mount_prime_directory(self):
        with Multipass(
            project=self.project, echoer=self.echoer_mock, is_ephemeral=False
        ) as instance:
            instance._mount_prime_directory()

        self.multipass_cmd_mock().mount.assert_called_once_with(
            source=mock.ANY,
            target="{}:{}".format(self.instance_name, "/root/prime"),
            uid_map=self.expected_uid_map,
            gid_map=self.expected_gid_map,
        )
Exemple #18
0
    def test_provision_project(self):
        multipass = Multipass(project=self.project, echoer=self.echoer_mock)

        # In the real world, MultipassCommand would return an error when
        # calling this on an instance that does not exist.
        multipass.provision_project('source.tar')

        self.multipass_cmd_mock().execute.assert_has_calls([
            mock.call(instance_name=self.instance_name,
                      command=['mkdir', 'project-name']),
            mock.call(
                instance_name=self.instance_name,
                command=['tar', '-xvf', 'source.tar', '-C', 'project-name']),
        ])
        self.multipass_cmd_mock().copy_files.assert_called_once_with(
            destination='{}:source.tar'.format(self.instance_name),
            source='source.tar')

        self.multipass_cmd_mock().launch.assert_not_called()
        self.multipass_cmd_mock().info.assert_not_called()
        self.multipass_cmd_mock().stop.assert_not_called()
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #19
0
    def test_build_project(self):
        multipass = Multipass(project=self.project, echoer=self.echoer_mock)

        # In the real world, MultipassCommand would return an error when
        # calling this on an instance that does not exist.
        multipass.build_project()

        self.multipass_cmd_mock().execute.assert_called_once_with(
            instance_name=self.instance_name,
            command=[
                "sh",
                "-c",
                "cd project-name; /snap/bin/snapcraft "
                "snap --output project-name_{}.snap".format(self.project.deb_arch),
            ],
        )

        self.multipass_cmd_mock().copy_files.assert_not_called()
        self.multipass_cmd_mock().launch.assert_not_called()
        self.multipass_cmd_mock().info.assert_not_called()
        self.multipass_cmd_mock().stop.assert_not_called()
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #20
0
    def test_ephemeral_instance_with_contextmanager(self):
        with Multipass(project=self.project,
                       echoer=self.echoer_mock,
                       is_ephemeral=True) as instance:
            instance.execute_step(steps.PULL)
            instance.execute_step(steps.BUILD)

        self.multipass_cmd_mock().launch.assert_called_once_with(
            instance_name=self.instance_name,
            cpus="2",
            mem="2G",
            disk="256G",
            image="snapcraft:core16",
        )
        # Given SnapInjector is mocked, we only need to verify the commands
        # called from the Multipass class.
        self.multipass_cmd_mock().execute.assert_has_calls([
            mock.call(
                instance_name=self.instance_name,
                hide_output=False,
                command=[
                    "sudo",
                    "-i",
                    "env",
                    "SNAPCRAFT_HAS_TTY=False",
                    "snapcraft",
                    "pull",
                ],
            ),
            mock.call(
                instance_name=self.instance_name,
                hide_output=False,
                command=[
                    "sudo",
                    "-i",
                    "env",
                    "SNAPCRAFT_HAS_TTY=False",
                    "snapcraft",
                    "build",
                ],
            ),
        ])
        self.assertThat(self.multipass_cmd_mock().info.call_count, Equals(3))
        self.multipass_cmd_mock().info.assert_has_calls([
            mock.call(instance_name=self.instance_name, output_format="json"),
            mock.call(instance_name=self.instance_name, output_format="json"),
        ])
        self.multipass_cmd_mock().stop.assert_called_once_with(
            instance_name=self.instance_name, time=10)
        self.multipass_cmd_mock().delete.assert_called_once_with(
            instance_name=self.instance_name, purge=True)
Exemple #21
0
    def test_destroy_instance_with_stop_delay_0(self):
        self.useFixture(
            fixtures.EnvironmentVariable(
                "SNAPCRAFT_BUILD_ENVIRONMENT_STOP_TIME", "0"))

        multipass = Multipass(project=self.project, echoer=self.echoer_mock)

        multipass.create()
        multipass.destroy()

        self.multipass_cmd_mock().stop.assert_called_once_with(
            instance_name=self.instance_name)
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #22
0
    def test_lifecycle(self):
        with Multipass(
            project=self.project, echoer=self.echoer_mock, is_ephemeral=False
        ) as instance:
            instance.mount_project()
            instance.execute_step(steps.PULL)

        self.multipass_cmd_mock().launch.assert_called_once_with(
            instance_name=self.instance_name,
            mem="2G",
            disk="256G",
            image=self.expected_image,
            cloud_init=mock.ANY,
        )
        self.multipass_cmd_mock().execute.assert_has_calls(
            [
                mock.call(
                    instance_name=self.instance_name,
                    hide_output=True,
                    command=["printenv", "HOME"],
                ),
                mock.call(
                    instance_name=self.instance_name,
                    hide_output=False,
                    command=["snapcraft", "pull"],
                ),
            ]
        )
        self.multipass_cmd_mock().mount.assert_called_once_with(
            source=mock.ANY,
            target="{}:{}".format(self.instance_name, "/home/multipass/project"),
        )
        self.multipass_cmd_mock().umount.assert_not_called()
        self.multipass_cmd_mock().info.assert_called_once_with(
            instance_name=self.instance_name, output_format="json"
        )

        self.multipass_cmd_mock().copy_files.assert_not_called()
        self.multipass_cmd_mock().stop.assert_called_once_with(
            instance_name=self.instance_name
        )
        self.multipass_cmd_mock().delete.assert_not_called()
Exemple #23
0
    def test_instance_with_contextmanager(self):
        with Multipass(project=self.project,
                       echoer=self.echoer_mock) as instance:
            instance.provision_project('source.tar')
            instance.build_project()
            instance.retrieve_snap()

        self.multipass_cmd_mock().launch.assert_called_once_with(
            image='16.04', instance_name=self.instance_name)
        self.multipass_cmd_mock().execute.assert_has_calls([
            mock.call(
                instance_name=self.instance_name,
                command=['sudo', 'snap', 'install', 'snapcraft', '--classic']),
            mock.call(instance_name=self.instance_name,
                      command=['mkdir', 'project-name']),
            mock.call(
                instance_name=self.instance_name,
                command=['tar', '-xvf', 'source.tar', '-C', 'project-name']),
            mock.call(instance_name=self.instance_name,
                      command=[
                          'sh', '-c', 'cd project-name; /snap/bin/snapcraft '
                          'snap --output project-name_{}.snap'.format(
                              self.project.deb_arch)
                      ]),
        ])
        self.multipass_cmd_mock().info.assert_called_once_with(
            instance_name=self.instance_name, output_format='json')

        self.multipass_cmd_mock().copy_files.assert_has_calls([
            mock.call(destination='{}:source.tar'.format(self.instance_name),
                      source='source.tar'),
            mock.call(destination='project-name_{}.snap'.format(
                self.project.deb_arch),
                      source='{}:project-name/project-name_{}.snap'.format(
                          self.instance_name, self.project.deb_arch)),
        ])
        self.multipass_cmd_mock().stop.assert_called_once_with(
            instance_name=self.instance_name)
        self.multipass_cmd_mock().delete.assert_called_once_with(
            instance_name=self.instance_name)
Exemple #24
0
    def test_lifecycle(self):
        with Multipass(project=self.project,
                       echoer=self.echoer_mock,
                       is_ephemeral=False) as instance:
            instance.mount_project()
            instance.execute_step(steps.PULL)

        self.multipass_cmd_mock().launch.assert_called_once_with(
            instance_name=self.instance_name,
            cpus="2",
            mem="2G",
            disk="256G",
            image=self.expected_image,
        )
        self.assertThat(self.multipass_cmd_mock().execute.call_count,
                        Equals(9))
        self.multipass_cmd_mock().execute.assert_has_calls([
            mock.call(
                command=[
                    "sudo",
                    "-i",
                    "env",
                    "SNAPCRAFT_HAS_TTY=False",
                    "snapcraft",
                    "refresh",
                ],
                hide_output=False,
                instance_name="snapcraft-project-name",
            ),
            mock.call(
                command=[
                    "sudo",
                    "-i",
                    "env",
                    "SNAPCRAFT_HAS_TTY=False",
                    "mv",
                    "/tmp/L3Jvb3QvLmJhc2hyYw==",
                    "/root/.bashrc",
                ],
                hide_output=False,
                instance_name="snapcraft-project-name",
            ),
            mock.call(
                command=[
                    "sudo",
                    "-i",
                    "env",
                    "SNAPCRAFT_HAS_TTY=False",
                    "chown",
                    "root:root",
                    "/root/.bashrc",
                ],
                hide_output=False,
                instance_name="snapcraft-project-name",
            ),
            mock.call(
                command=[
                    "sudo",
                    "-i",
                    "env",
                    "SNAPCRAFT_HAS_TTY=False",
                    "chmod",
                    "0600",
                    "/root/.bashrc",
                ],
                hide_output=False,
                instance_name="snapcraft-project-name",
            ),
            mock.call(
                command=[
                    "sudo",
                    "-i",
                    "env",
                    "SNAPCRAFT_HAS_TTY=False",
                    "mv",
                    "/tmp/L2Jpbi9fc25hcGNyYWZ0X3Byb21wdA==",
                    "/bin/_snapcraft_prompt",
                ],
                hide_output=False,
                instance_name="snapcraft-project-name",
            ),
            mock.call(
                command=[
                    "sudo",
                    "-i",
                    "env",
                    "SNAPCRAFT_HAS_TTY=False",
                    "chown",
                    "root:root",
                    "/bin/_snapcraft_prompt",
                ],
                hide_output=False,
                instance_name="snapcraft-project-name",
            ),
            mock.call(
                command=[
                    "sudo",
                    "-i",
                    "env",
                    "SNAPCRAFT_HAS_TTY=False",
                    "chmod",
                    "0755",
                    "/bin/_snapcraft_prompt",
                ],
                hide_output=False,
                instance_name="snapcraft-project-name",
            ),
            mock.call(
                command=[
                    "sudo",
                    "-i",
                    "env",
                    "SNAPCRAFT_HAS_TTY=False",
                    "printenv",
                    "HOME",
                ],
                hide_output=True,
                instance_name="snapcraft-project-name",
            ),
            mock.call(
                command=[
                    "sudo",
                    "-i",
                    "env",
                    "SNAPCRAFT_HAS_TTY=False",
                    "snapcraft",
                    "pull",
                ],
                hide_output=False,
                instance_name="snapcraft-project-name",
            ),
        ])
        self.multipass_cmd_mock().mount.assert_called_once_with(
            source=mock.ANY,
            target="{}:{}".format(self.instance_name, "/root/project"),
            uid_map=self.expected_uid_map,
            gid_map=self.expected_gid_map,
        )
        self.multipass_cmd_mock().umount.assert_not_called()
        self.assertThat(self.multipass_cmd_mock().info.call_count, Equals(3))
        self.multipass_cmd_mock().info.assert_has_calls([
            mock.call(instance_name=self.instance_name, output_format="json"),
            mock.call(instance_name=self.instance_name, output_format="json"),
        ])
        self.assertThat(self.multipass_cmd_mock().copy_files.call_count,
                        Equals(2))
        self.multipass_cmd_mock().copy_files.assert_has_calls([
            mock.call(
                source=mock.ANY,
                destination="snapcraft-project-name:/tmp/L3Jvb3QvLmJhc2hyYw==",
            ),
            mock.call(
                source=mock.ANY,
                destination=
                "snapcraft-project-name:/tmp/L2Jpbi9fc25hcGNyYWZ0X3Byb21wdA==",
            ),
        ])
        self.multipass_cmd_mock().stop.assert_called_once_with(
            instance_name=self.instance_name, time=10)
        self.multipass_cmd_mock().delete.assert_not_called()
    def test_plaftorm_and_base_unsupported(self):
        project = get_project(base="core17")

        multipass = Multipass(project=project, echoer=self.echoer_mock)

        self.assertRaises(errors.UnsupportedHostError, multipass.create)
    def test_instance_with_contextmanager(self):
        fake_snapd = fixture_setup.FakeSnapd()
        self.useFixture(fake_snapd)
        fake_snapd.snaps_result = []
        fake_snapd.find_result = [
            {
                "core": {
                    "id": "2kkitQ",
                    "channels": {
                        "latest/stable": {
                            "confinement": "strict",
                            "revision": "123"
                        }
                    },
                }
            },
            {
                "snapcraft": {
                    "id": "3lljuR",
                    "channels": {
                        "latest/stable": {
                            "confinement": "classic",
                            "revision": "345"
                        }
                    },
                }
            },
        ]

        self.get_assertion_mock.side_effect = [b"fake-assertion-account-store"]

        with Multipass(project=self.project,
                       echoer=self.echoer_mock) as instance:
            instance.provision_project("source.tar")
            instance.build_project()
            instance.retrieve_snap()

        self.multipass_cmd_mock().launch.assert_called_once_with(
            image="16.04", instance_name=self.instance_name)
        self.multipass_cmd_mock().execute.assert_has_calls([
            mock.call(
                instance_name=self.instance_name,
                command=["sudo", "snap", "set", "core", mock.ANY],
            ),
            mock.call(
                instance_name=self.instance_name,
                command=["sudo", "snap", "watch", "--last=auto-refresh"],
            ),
            mock.call(
                instance_name=self.instance_name,
                command=["sudo", "snap", "ack", mock.ANY],
            ),
            mock.call(
                instance_name=self.instance_name,
                command=["sudo", "snap", "install", "core"],
            ),
            mock.call(
                instance_name=self.instance_name,
                command=["sudo", "snap", "install", "--classic", "snapcraft"],
            ),
            mock.call(instance_name=self.instance_name,
                      command=["mkdir", "project-name"]),
            mock.call(
                instance_name=self.instance_name,
                command=["tar", "-xvf", "source.tar", "-C", "project-name"],
            ),
            mock.call(
                instance_name=self.instance_name,
                command=[
                    "sh",
                    "-c",
                    "cd project-name; /snap/bin/snapcraft "
                    "snap --output project-name_{}.snap".format(
                        self.project.deb_arch),
                ],
            ),
        ])
        self.multipass_cmd_mock().info.assert_called_once_with(
            instance_name=self.instance_name, output_format="json")

        self.multipass_cmd_mock().copy_files.assert_has_calls([
            mock.call(
                destination="{}:source.tar".format(self.instance_name),
                source="source.tar",
            ),
            mock.call(
                destination="project-name_{}.snap".format(
                    self.project.deb_arch),
                source="{}:project-name/project-name_{}.snap".format(
                    self.instance_name, self.project.deb_arch),
            ),
        ])
        self.multipass_cmd_mock().stop.assert_called_once_with(
            instance_name=self.instance_name)
        self.multipass_cmd_mock().delete.assert_called_once_with(
            instance_name=self.instance_name)