def test_snap_containerized_exists_running(self, mock_getuid, mock_container_run): self.useFixture( fixtures.EnvironmentVariable('SUDO_UID', self.SUDO_UID)) mock_getuid.return_value = self.getuid fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) # Container was created before and is running fake_lxd.name = 'local:snapcraft-snap-test' fake_lxd.status = 'Running' self.useFixture(fixtures.EnvironmentVariable( 'SNAPCRAFT_CONTAINER_BUILDS', '1')) self.make_snapcraft_yaml() self.run_command(['snap']) source = os.path.realpath(os.path.curdir) project_folder = '/root/build_snap-test' fake_lxd.check_call_mock.assert_has_calls([ call(['lxc', 'config', 'device', 'add', fake_lxd.name, project_folder, 'disk', 'source={}'.format(source), 'path={}'.format(project_folder)]), call(['lxc', 'stop', '-f', fake_lxd.name]), ]) mock_container_run.assert_has_calls([ call(['python3', '-c', mock.ANY]), call(['snapcraft', 'snap', '--output', 'snap-test_1.0_amd64.snap'], cwd=project_folder, user='******'), ])
def test_snap_containerized_exists_stopped(self, mock_inject, mock_container_run, mock_getuid): self.useFixture( fixtures.EnvironmentVariable('SUDO_UID', self.SUDO_UID)) mock_getuid.return_value = self.getuid mock_container_run.side_effect = lambda cmd, **kwargs: cmd fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) # Container was created before, and isn't running fake_lxd.devices = '{"/root/build_snap-test":[]}' fake_lxd.name = 'local:snapcraft-snap-test' fake_lxd.status = 'Stopped' fake_logger = fixtures.FakeLogger(level=logging.INFO) self.useFixture(fake_logger) self.useFixture(fixtures.EnvironmentVariable( 'SNAPCRAFT_CONTAINER_BUILDS', '1')) self.make_snapcraft_yaml() result = self.run_command(['snap']) self.assertThat(result.exit_code, Equals(0)) self.assertIn( 'Waiting for a network connection...\n' 'Network connection established\n', fake_logger.output) container_name = 'local:snapcraft-snap-test' project_folder = '/root/build_snap-test' fake_lxd.check_call_mock.assert_has_calls([ call(['lxc', 'config', 'set', container_name, 'environment.SNAPCRAFT_SETUP_CORE', '1']), call(['lxc', 'config', 'set', container_name, 'environment.LC_ALL', 'C.UTF-8']), call(['lxc', 'config', 'set', container_name, 'environment.SNAPCRAFT_IMAGE_INFO', '{"fingerprint": "test-fingerprint", ' '"architecture": "test-architecture", ' '"created_at": "test-created-at"}']), call(['lxc', 'config', 'set', container_name, 'raw.idmap', 'both {} {}'.format( self.expected_idmap, 0)]), call(['lxc', 'config', 'device', 'remove', container_name, project_folder]), call(['lxc', 'config', 'device', 'add', container_name, 'fuse', 'unix-char', 'path=/dev/fuse']), call(['lxc', 'start', container_name]), call(['lxc', 'stop', '-f', container_name]), ]) mock_container_run.assert_has_calls([ call(['python3', '-c', mock.ANY]), call(['snapcraft', 'snap', '--output', 'snap-test_1.0_amd64.snap'], cwd=project_folder, user='******'), ]) # Ensure there's no unexpected calls eg. two network checks self.assertThat(mock_container_run.call_count, Equals(2))
def test_cleanbuild(self): self.useFixture(fixture_setup.FakeLXD()) result = self.run_command(['cleanbuild']) self.assertThat(result.exit_code, Equals(0)) self.assertIn( 'Setting up container with project assets\n' 'Retrieved snap-test_1.0_amd64.snap\n', self.fake_logger.output) with tarfile.open('snap-test_1.0_source.tar.bz2') as tar: tar_members = tar.getnames() for f in self.files_no_tar: f = os.path.relpath(f) self.assertFalse('./{}'.format(f) in tar_members, '{} should not be in {}'.format(f, tar_members)) for f in self.files_tar: f = os.path.relpath(f) self.assertTrue('./{}'.format(f) in tar_members, '{} should be in {}'.format(f, tar_members)) # Also assert that the snapcraft.yaml made it into the cleanbuild tar self.assertThat(tar_members, Contains(os.path.join('.', 'snap', 'snapcraft.yaml')), 'snap/snapcraft unexpectedly excluded from tarball')
def test_invalid_remote(self): fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) exception = self.assertRaises(InvalidContainerRemoteError, self.run_command, ['cleanbuild', '--remote', 'foo/bar']) self.assertThat(exception.remote, Equals('foo/bar'))
def test_snap_containerized(self, mock_inject, mock_container_run, mock_getuid): self.useFixture( fixtures.EnvironmentVariable('SUDO_UID', self.SUDO_UID)) mock_getuid.return_value = self.getuid mock_container_run.side_effect = lambda cmd, **kwargs: cmd fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) fake_logger = fixtures.FakeLogger(level=logging.INFO) self.useFixture(fake_logger) self.useFixture(fixtures.EnvironmentVariable( 'SNAPCRAFT_CONTAINER_BUILDS', '1')) self.make_snapcraft_yaml() result = self.run_command(['snap']) self.assertThat(result.exit_code, Equals(0)) source = os.path.realpath(os.path.curdir) self.assertThat(fake_logger.output, Contains( 'Waiting for a network connection...\n' 'Network connection established\n' 'Mounting {} into container\n'.format(source))) container_name = 'local:snapcraft-snap-test' project_folder = '/root/build_snap-test' fake_lxd.check_call_mock.assert_has_calls([ call(['lxc', 'init', 'ubuntu:xenial', container_name]), call(['lxc', 'config', 'set', container_name, 'environment.SNAPCRAFT_SETUP_CORE', '1']), call(['lxc', 'config', 'set', container_name, 'environment.LC_ALL', 'C.UTF-8']), call(['lxc', 'config', 'set', container_name, 'environment.SNAPCRAFT_IMAGE_INFO', '{"fingerprint": "test-fingerprint", ' '"architecture": "test-architecture", ' '"created_at": "test-created-at"}']), call(['lxc', 'config', 'set', container_name, 'raw.idmap', 'both {} {}'.format( self.expected_idmap, '0')]), call(['lxc', 'config', 'device', 'add', container_name, 'fuse', 'unix-char', 'path=/dev/fuse']), call(['lxc', 'start', container_name]), call(['lxc', 'config', 'device', 'add', container_name, project_folder, 'disk', 'source={}'.format(source), 'path={}'.format(project_folder)]), call(['lxc', 'stop', '-f', container_name]), ]) mock_container_run.assert_has_calls([ call(['python3', '-c', mock.ANY]), call(['apt-get', 'update']), call(['apt-get', 'install', 'squashfuse', '-y']), call(['snapcraft', 'snap', '--output', 'snap-test_1.0_amd64.snap'], cwd=project_folder, user='******'), ])
def setUp(self): super().setUp() self.fake_lxd = fixture_setup.FakeLXD() self.useFixture(self.fake_lxd) self.fake_lxd.kernel_arch = self.server self.fake_filesystem = fixture_setup.FakeFilesystem() self.useFixture(self.fake_filesystem) self.fake_logger = fixtures.FakeLogger(level=logging.INFO) self.useFixture(self.fake_logger) self.project_options = ProjectOptions(target_deb_arch=self.target_arch)
def test_refresh_fails_without_env_var(self, mock_container_run): mock_container_run.side_effect = lambda cmd, **kwargs: cmd fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) fake_filesystem = fixture_setup.FakeFilesystem() self.useFixture(fake_filesystem) self.make_snapcraft_yaml() self.assertRaises(SnapcraftEnvironmentError, self.run_command, ['refresh']) mock_container_run.assert_not_called()
def test_clean_containerized_noop(self): fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) self.useFixture( fixtures.EnvironmentVariable('SNAPCRAFT_CONTAINER_BUILDS', self.snapcraft_container_builds)) self.make_snapcraft_yaml(n=3) result = self.run_command(['clean']) self.assertThat(result.exit_code, Equals(0)) # clean should be a noop if no container exists yet/ anymore fake_lxd.check_call_mock.assert_not_called()
def test_clean_containerized_with_part(self): fake_lxd = fixture_setup.FakeLXD() fake_lxd.name = 'local:snapcraft-clean-test' fake_lxd.status = 'Stopped' self.useFixture(fake_lxd) self.useFixture( fixtures.EnvironmentVariable('SNAPCRAFT_CONTAINER_BUILDS', self.snapcraft_container_builds)) self.make_snapcraft_yaml(n=3) result = self.run_command(['clean', 'clean1']) self.assertThat(result.exit_code, Equals(0)) # clean with parts should NOT delete the container fake_lxd.check_call_mock.assert_not_called()
def test_cleanbuild_debug_prepended_goes_to_shell_on_errors(self): fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) def call_effect(*args, **kwargs): # Fail on an actual snapcraft command and not the command # for the installation of it. if 'snapcraft snap' in ' '.join(args[0]): raise subprocess.CalledProcessError(returncode=255, cmd=args[0]) fake_lxd.check_call_mock.side_effect = call_effect result = self.run_command(['--debug', 'cleanbuild']) self.assertThat(result.exit_code, Equals(0)) self.assertThat(self.fake_logger.output, Contains('Debug mode enabled, dropping into a shell'))
def test_clean_containerized_with_part(self): fake_lxd = fixture_setup.FakeLXD() fake_lxd.name = "local:snapcraft-clean-test" fake_lxd.status = "Stopped" self.useFixture(fake_lxd) # Container should not be initialized at all fake_lxd.check_output_mock.side_effect = FileNotFoundError("lxc") self.useFixture( fixtures.EnvironmentVariable("SNAPCRAFT_CONTAINER_BUILDS", self.snapcraft_container_builds)) self.make_snapcraft_yaml(n=3) result = self.run_command(["clean", "clean1"]) self.assertThat(result.exit_code, Equals(0)) # clean with parts should NOT delete the container fake_lxd.check_call_mock.assert_not_called()
def test_update_containerized_exists_running(self, mock_getuid, mock_container_run): mock_container_run.side_effect = lambda cmd, **kwargs: cmd mock_getuid.return_value = 1234 fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) # Container was created before and is running fake_lxd.name = "local:snapcraft-snap-test" fake_lxd.status = "Running" self.useFixture(fixtures.EnvironmentVariable("SNAPCRAFT_CONTAINER_BUILDS", "1")) self.make_snapcraft_yaml(self.yaml_template) result = self.run_command(["update"]) self.assertThat(result.exit_code, Equals(0)) project_folder = "/root/build_snap-test" mock_container_run.assert_has_calls( [call(["snapcraft", "update"], cwd=project_folder, user="******")] )
def test_refresh(self, mock_container_run): mock_container_run.side_effect = lambda cmd, **kwargs: cmd fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) fake_filesystem = fixture_setup.FakeFilesystem() self.useFixture(fake_filesystem) self.useFixture( fixtures.EnvironmentVariable('SNAPCRAFT_BUILD_ENVIRONMENT', 'lxd')) self.make_snapcraft_yaml() self.run_command(['refresh']) mock_container_run.assert_has_calls([ call(['apt-get', 'update']), call(['apt-get', 'upgrade', '-y']), call(['snap', 'refresh']), ]) self.assertThat(fake_lxd.name, Equals('local:snapcraft-snap-test'))
def test_refresh(self, mock_container_run): mock_container_run.side_effect = lambda cmd, **kwargs: cmd fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) fake_filesystem = fixture_setup.FakeFilesystem() self.useFixture(fake_filesystem) self.useFixture( fixtures.EnvironmentVariable("SNAPCRAFT_BUILD_ENVIRONMENT", "lxd")) self.make_snapcraft_yaml() self.run_command(["refresh"]) mock_container_run.assert_has_calls([ call(["apt-get", "update"]), call(["apt-get", "upgrade", "-y"]), call(["snap", "refresh"]), ]) self.assertThat(fake_lxd.name, Equals("local:snapcraft-snap-test"))
def test_snap_containerized_invalid_remote(self, mock_open, mock_makedirs, mock_rmtree, mock_container_run): mock_container_run.side_effect = lambda cmd, **kwargs: cmd mock_open.return_value = mock.MagicMock(spec=open) fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) fake_logger = fixtures.FakeLogger(level=logging.INFO) self.useFixture(fake_logger) self.useFixture( fixtures.EnvironmentVariable('SNAPCRAFT_CONTAINER_BUILDS', 'foo/bar')) self.make_snapcraft_yaml() exception = self.assertRaises( snapcraft.internal.errors.InvalidContainerRemoteError, self.run_command, ['--debug', 'snap']) self.assertThat(exception.remote, Equals('foo/bar'))
def test_clean_containerized_pull_retains_container( self, mock_lifecycle_clean): fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) # Container was created before, and isn't running fake_lxd.name = '{}:snapcraft-clean-test'.format(self.remote) fake_lxd.status = 'Stopped' self.useFixture( fixtures.EnvironmentVariable('SNAPCRAFT_CONTAINER_BUILDS', self.snapcraft_container_builds)) self.make_snapcraft_yaml(n=3) result = self.run_command(['clean', '-s', 'pull']) self.assertThat(result.exit_code, Equals(0)) # clean pull should NOT delete the container fake_lxd.check_call_mock.assert_not_called() # clean should be called normally, outside of the container mock_lifecycle_clean.assert_has_calls([call(ANY, (), 'pull')])
def test_snap_containerized_remote(self, mock_geteuid, mock_pipe, mock_container_run): mock_container_run.side_effect = lambda cmd, **kwargs: cmd mock_pipe.return_value = (9, 9) mock_geteuid.return_value = 1234 fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) fake_filesystem = fixture_setup.FakeFilesystem() self.useFixture(fake_filesystem) fake_logger = fixtures.FakeLogger(level=logging.INFO) self.useFixture(fake_logger) self.useFixture( fixtures.EnvironmentVariable('SNAPCRAFT_CONTAINER_BUILDS', 'myremote')) self.useFixture(fixtures.EnvironmentVariable('USER', 'user')) self.make_snapcraft_yaml() result = self.run_command(['--debug', 'snap']) self.assertThat(result.exit_code, Equals(0)) source = os.path.realpath(os.path.curdir) self.assertThat( fake_logger.output, Contains( "Using LXD remote 'myremote' from SNAPCRAFT_CONTAINER_BUILDS")) project_folder = '/home/user/build_snap-test' mock_container_run.assert_has_calls([ call(['apt-get', 'install', '-y', 'sshfs']), ]) fake_lxd.popen_mock.assert_has_calls([ call(['/usr/lib/sftp-server'], stdin=9, stdout=9), call([ 'lxc', 'exec', fake_lxd.name, '--', 'sudo', '-H', '-u', 'user', 'sshfs', '-o', 'slave', '-o', 'nonempty', ':{}'.format(source), project_folder ], stdin=9, stdout=9), ])
def test_clean_containerized_exists_stopped(self, mock_lifecycle_clean): fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) # Container was created before, and isn't running fake_lxd.name = "{}:snapcraft-clean-test".format(self.remote) fake_lxd.status = "Stopped" self.useFixture( fixtures.EnvironmentVariable("SNAPCRAFT_CONTAINER_BUILDS", self.snapcraft_container_builds)) self.make_snapcraft_yaml(n=3) result = self.run_command(["clean"]) self.assertThat(result.exit_code, Equals(0)) # clean with no parts should delete the container fake_lxd.check_call_mock.assert_has_calls( [call(["lxc", "delete", "-f", fake_lxd.name])]) # no other commands should be run in the container self.assertThat(fake_lxd.check_call_mock.call_count, Equals(1)) # clean should be called normally, outside of the container mock_lifecycle_clean.assert_has_calls([call(ANY, (), steps.PULL)])
def setUp(self): super().setUp() self.fake_lxd = fixture_setup.FakeLXD() self.useFixture(self.fake_lxd) self.fake_lxd.kernel_arch = self.server self.fake_logger = fixtures.FakeLogger(level=logging.INFO) self.useFixture(self.fake_logger) patcher = patch("snapcraft.internal.lxd._containerbuild.SnapInjector") self.snap_injector_mock = patcher.start() self.addCleanup(patcher.stop) self.snapcraft_yaml = fixture_setup.SnapcraftYaml(self.path) self.useFixture(self.snapcraft_yaml) self.project = Project( snapcraft_yaml_file_path=self.snapcraft_yaml. snapcraft_yaml_file_path, target_deb_arch=self.target_arch, ) self.useFixture(fixtures.EnvironmentVariable("SUDO_UID", "1000"))
def test_snap_containerized_exists_running(self, mock_getuid, mock_container_run): self.useFixture(fixtures.EnvironmentVariable("SUDO_UID", self.SUDO_UID)) mock_getuid.return_value = self.getuid fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) # Container was created before and is running fake_lxd.name = "local:snapcraft-snap-test" fake_lxd.status = "Running" self.useFixture( fixtures.EnvironmentVariable("SNAPCRAFT_CONTAINER_BUILDS", "1")) self.make_snapcraft_yaml() self.run_command(["snap"]) source = os.path.realpath(os.path.curdir) project_folder = "/root/build_snap-test" fake_lxd.check_call_mock.assert_has_calls([ call([ "lxc", "config", "device", "add", fake_lxd.name, project_folder, "disk", "source={}".format(source), "path={}".format(project_folder), ]), call(["lxc", "stop", "-f", fake_lxd.name]), ]) mock_container_run.assert_has_calls([ call(["python3", "-c", mock.ANY]), call(["snapcraft", "prime"], cwd=mock.ANY, user=mock.ANY), ]) self.pack_mock.assert_called_once_with(self.prime_dir, None)
def test_snap_containerized_exists_stopped(self, mock_inject, mock_container_run, mock_getuid): self.useFixture(fixtures.EnvironmentVariable("SUDO_UID", self.SUDO_UID)) mock_getuid.return_value = self.getuid mock_container_run.side_effect = lambda cmd, **kwargs: cmd fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) # Container was created before, and isn't running fake_lxd.devices = '{"/root/build_snap-test":[]}' fake_lxd.name = "local:snapcraft-snap-test" fake_lxd.status = "Stopped" fake_logger = fixtures.FakeLogger(level=logging.INFO) self.useFixture(fake_logger) self.useFixture( fixtures.EnvironmentVariable("SNAPCRAFT_CONTAINER_BUILDS", "1")) self.make_snapcraft_yaml() result = self.run_command(["snap"]) self.assertThat(result.exit_code, Equals(0)) self.assertIn( "Waiting for a network connection...\nNetwork connection established\n", fake_logger.output, ) container_name = "local:snapcraft-snap-test" project_folder = "/root/build_snap-test" fake_lxd.check_call_mock.assert_has_calls([ call([ "lxc", "config", "set", container_name, "environment.SNAPCRAFT_SETUP_CORE", "1", ]), call([ "lxc", "config", "set", "local:snapcraft-snap-test", "environment.SNAPCRAFT_MANAGED_HOST", "yes", ]), call([ "lxc", "config", "set", container_name, "environment.LC_ALL", "C.UTF-8", ]), call([ "lxc", "config", "set", container_name, "environment.SNAPCRAFT_IMAGE_INFO", '{"fingerprint": "test-fingerprint", ' '"architecture": "test-architecture", ' '"created_at": "test-created-at"}', ]), call([ "lxc", "config", "set", container_name, "raw.idmap", "both {} {}".format(self.expected_idmap, 0), ]), call([ "lxc", "config", "device", "remove", container_name, project_folder, ]), call([ "lxc", "config", "device", "add", container_name, "fuse", "unix-char", "path=/dev/fuse", ]), call(["lxc", "start", container_name]), call(["lxc", "stop", "-f", container_name]), ]) mock_container_run.assert_has_calls([ call(["python3", "-c", mock.ANY]), call(["snapcraft", "prime"], cwd=mock.ANY, user=mock.ANY), ]) # Ensure there's no unexpected calls eg. two network checks self.assertThat(mock_container_run.call_count, Equals(2)) self.pack_mock.assert_called_once_with(self.prime_dir, None)
def test_cleanbuild(self): fake_logger = fixtures.FakeLogger(level=logging.INFO) self.useFixture(fake_logger) self.useFixture(fixture_setup.FakeLXD())
def test_snap_containerized(self, mock_inject, mock_container_run, mock_getuid): self.useFixture(fixtures.EnvironmentVariable("SUDO_UID", self.SUDO_UID)) mock_getuid.return_value = self.getuid mock_container_run.side_effect = lambda cmd, **kwargs: cmd fake_lxd = fixture_setup.FakeLXD() self.useFixture(fake_lxd) fake_logger = fixtures.FakeLogger(level=logging.INFO) self.useFixture(fake_logger) self.useFixture( fixtures.EnvironmentVariable("SNAPCRAFT_CONTAINER_BUILDS", "1")) self.make_snapcraft_yaml() result = self.run_command(["snap"]) self.assertThat(result.exit_code, Equals(0)) source = os.path.realpath(os.path.curdir) self.assertThat( fake_logger.output, Contains("Waiting for a network connection...\n" "Network connection established\n" "Mounting {} into container\n".format(source)), ) container_name = "local:snapcraft-snap-test" project_folder = "/root/build_snap-test" fake_lxd.check_call_mock.assert_has_calls([ call(["lxc", "init", "ubuntu:xenial", container_name]), call([ "lxc", "config", "set", container_name, "environment.SNAPCRAFT_SETUP_CORE", "1", ]), call([ "lxc", "config", "set", "local:snapcraft-snap-test", "environment.SNAPCRAFT_MANAGED_HOST", "yes", ]), call([ "lxc", "config", "set", container_name, "environment.LC_ALL", "C.UTF-8", ]), call([ "lxc", "config", "set", container_name, "environment.SNAPCRAFT_IMAGE_INFO", '{"fingerprint": "test-fingerprint", ' '"architecture": "test-architecture", ' '"created_at": "test-created-at"}', ]), call([ "lxc", "config", "set", container_name, "raw.idmap", "both {} {}".format(self.expected_idmap, "0"), ]), call([ "lxc", "config", "device", "add", container_name, "fuse", "unix-char", "path=/dev/fuse", ]), call(["lxc", "start", container_name]), call([ "lxc", "config", "device", "add", container_name, project_folder, "disk", "source={}".format(source), "path={}".format(project_folder), ]), call(["lxc", "stop", "-f", container_name]), ]) mock_container_run.assert_has_calls([ call(["python3", "-c", mock.ANY]), call(["apt-get", "update"]), call(["apt-get", "install", "squashfuse", "-y"]), call(["snapcraft", "prime"], cwd=mock.ANY, user=mock.ANY), ]) self.pack_mock.assert_called_once_with(self.prime_dir, None)