def test_dump_broken_symlink(self): self.options.source = 'src' plugin = DumpPlugin('dump', self.options, self.project_options) os.makedirs(os.path.join(plugin.builddir, 'src')) with open(os.path.join(plugin.builddir, 'src', 'file'), 'w') as f: f.write('foo') with open('unsnapped', 'w') as f: f.write('bar') symlinks = [ # This symlink is valid in source, but broken when snapped. { 'source': '../../../unsnapped', 'link_name': os.path.join( plugin.builddir, 'src', 'bad_relative'), 'destination': os.path.join( plugin.installdir, 'src', 'bad_relative'), 'expected_contents': 'bar', }, ] for symlink in symlinks: os.symlink(symlink['source'], symlink['link_name']) plugin.pull() raised = self.assertRaises(FileNotFoundError, plugin.build) self.assertThat( str(raised), Equals('{!r} is a broken symlink pointing outside the snap'.format( os.path.join(plugin.builddir, 'src', 'bad_relative'))))
def test_dump_symlinks(self): plugin = DumpPlugin('dump', self.options, self.project_options) os.makedirs(os.path.join(plugin.builddir, 'subdir')) with open(os.path.join(plugin.builddir, 'file'), 'w') as f: f.write('foo') symlinks = [ { 'source': 'file', 'link_name': os.path.join(plugin.builddir, 'relative1'), 'destination': os.path.join(plugin.installdir, 'relative1'), 'expected_realpath': os.path.join(plugin.installdir, 'file'), 'expected_contents': 'foo', }, { 'source': os.path.join('..', 'file'), 'link_name': os.path.join( plugin.builddir, 'subdir', 'relative2'), 'destination': os.path.join( plugin.installdir, 'subdir', 'relative2'), 'expected_realpath': os.path.join(plugin.installdir, 'file'), 'expected_contents': 'foo', }, { 'source': os.path.join('..', '..', 'install', 'file'), 'link_name': os.path.join( plugin.builddir, 'subdir', 'relative3'), 'destination': os.path.join( plugin.installdir, 'subdir', 'relative3'), 'expected_realpath': os.path.join(plugin.installdir, 'file'), 'expected_contents': 'foo', }, ] for symlink in symlinks: os.symlink(symlink['source'], symlink['link_name']) plugin.build() with open(os.path.join(plugin.installdir, 'file'), 'r') as f: self.assertThat(f.read(), Equals('foo')) for symlink in symlinks: destination = symlink['destination'] self.assertTrue( os.path.islink(destination), 'Expected {!r} to be a symlink'.format(destination)) self.assertThat( os.path.realpath(destination), Equals(symlink['expected_realpath']), 'Expected {!r} to be a relative path to {!r}'.format( destination, symlink['expected_realpath'])) with open(destination, 'r') as f: self.assertThat(f.read(), Equals(symlink['expected_contents']))
def test_dump_symlinks_that_should_be_followed(self): # TODO: Move to an integration test plugin = DumpPlugin('dump', self.options, self.project_options) os.makedirs(os.path.join(plugin.builddir, 'src')) with open(os.path.join(plugin.builddir, 'src', 'file'), 'w') as f: f.write('foo') with open('unsnapped', 'w') as f: f.write('bar') symlinks = [ # Links with an absolute path should be followed { 'source': os.path.abspath(os.path.join(plugin.builddir, 'src', 'file')), 'link_name': os.path.join(plugin.builddir, 'src', 'absolute'), 'destination': os.path.join(plugin.installdir, 'src', 'absolute'), 'expected_contents': 'foo', }, # Links with a relative path that points outside of the snap # should also be followed { 'source': '../../../../unsnapped', 'link_name': os.path.join(plugin.builddir, 'src', 'bad_relative'), 'destination': os.path.join(plugin.installdir, 'src', 'bad_relative'), 'expected_contents': 'bar', }, ] for symlink in symlinks: os.symlink(symlink['source'], symlink['link_name']) plugin.build() with open(os.path.join(plugin.installdir, 'src', 'file'), 'r') as f: self.assertEqual(f.read(), 'foo') for symlink in symlinks: destination = symlink['destination'] with self.subTest('link: {}'.format(destination)): self.assertFalse( os.path.islink(destination), 'Expected {!r} to be a copy rather than a ' 'symlink'.format(destination)) with open(destination, 'r') as f: self.assertEqual(f.read(), symlink['expected_contents'])
def test_dumping_with_contents(self): open('file1', 'w').close() open('file2', 'w').close() os.mkdir('dir1') open(os.path.join('dir1', 'subfile1'), 'w').close() plugin = DumpPlugin('dump', self.options, self.project_options) plugin.pull() plugin.build() contents = os.listdir(plugin.installdir) contents.sort() self.assertEqual(contents, ['dir1', 'file1', 'file2']) self.assertEqual(os.listdir(os.path.join(plugin.installdir, 'dir1')), ['subfile1'])
def test_dumping_with_contents(self): plugin = DumpPlugin('dump', self.options, self.project_options) os.makedirs(plugin.builddir) open(os.path.join(plugin.builddir, 'file1'), 'w').close() open(os.path.join(plugin.builddir, 'file2'), 'w').close() os.mkdir(os.path.join(plugin.builddir, 'dir1')) open(os.path.join(plugin.builddir, 'dir1', 'subfile1'), 'w').close() plugin.build() contents = os.listdir(plugin.installdir) contents.sort() self.assertThat(contents, Equals(['dir1', 'file1', 'file2'])) self.assertThat(os.listdir(os.path.join(plugin.installdir, 'dir1')), Equals(['subfile1']))
def test_dump_symlinks_to_libc(self): plugin = DumpPlugin('dump', self.options, self.project_options) os.makedirs(plugin.builddir) # Even though this symlink is absolute, since it's to libc the copy # plugin shouldn't try to follow it or modify it. libc_libs = snapcraft.repo.get_pkg_libs('libc6') # We don't care which lib we're testing with, as long as it's a .so. libc_library_path = [lib for lib in libc_libs if '.so' in lib][0] os.symlink(libc_library_path, os.path.join(plugin.builddir, 'libc-link')) plugin.build() self.assertThat(os.path.join(plugin.installdir, 'libc-link'), tests.LinkExists(libc_library_path))
def test_dumping_nothing(self): plugin = DumpPlugin('dump', self.options, self.project_options) os.makedirs(plugin.builddir) plugin.build() self.assertEqual(os.listdir(plugin.installdir), [])
def test_dump_enable_cross_compilation(self): plugin = DumpPlugin('dump', self.options, self.project_options) plugin.enable_cross_compilation()