Пример #1
0
    def test_invalid_yaml_invalid_confinement_types(self, mock_loadPlugin):
        invalid_confinement_types = [
            'foo',
            'strict-',
            '_devmode',
        ]

        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)

        for confinement_type in invalid_confinement_types:
            with self.subTest(key=confinement_type):
                self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: nothing
confinement: {}

parts:
  part1:
    plugin: go
    stage-packages: [fswebcam]
""".format(confinement_type))
                with self.assertRaises(SnapcraftSchemaError) as raised:
                    internal_yaml.Config()

                self.assertEqual(
                    raised.exception.message,
                    "The 'confinement' property does not match the required "
                    "schema: '{}' is not one of ['devmode', 'strict']".format(
                        confinement_type))
Пример #2
0
    def test_config_adds_vcs_packages_to_build_packages_from_types(self):
        scenarios = [
            ('git', 'git'),
            ('hg', 'mercurial'),
            ('mercurial', 'mercurial'),
            ('bzr', 'bzr'),
            ('tar', 'tar'),
            ('svn', 'subversion'),
            ('subversion', 'subversion'),
        ]
        yaml_t = """name: test
version: "1"
summary: test
description: test
confinement: strict

parts:
  part1:
    source: http://something/somewhere
    source-type: {0}
    plugin: autotools
"""

        for s in scenarios:
            with self.subTest(key=(s[1])):
                self.make_snapcraft_yaml(yaml_t.format(s[0]))
                c = internal_yaml.Config()

                self.assertTrue(
                    s[1] in c.build_tools,
                    '{} not found in {}'.format(s[1], c.build_tools))
Пример #3
0
    def test_config_loop(self):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)

        self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: test
confinement: strict

parts:
  p1:
    plugin: tar-content
    source: .
    after: [p2]
  p2:
    plugin: tar-content
    source: .
    after: [p1]
""")
        with self.assertRaises(internal_yaml.SnapcraftLogicError) as raised:
            internal_yaml.Config()

        self.assertEqual(
            raised.exception.message,
            'circular dependency chain found in parts definition')
Пример #4
0
    def test_config_adds_vcs_packages_to_build_packages(self):
        scenarios = [
            ('git://github.com/ubuntu-core/snapcraft.git', 'git'),
            ('lp:ubuntu-push', 'bzr'),
            ('https://github.com/ubuntu-core/snapcraft/archive/2.0.1.tar.gz',
             'tar'),
        ]
        yaml_t = """name: test
version: "1"
summary: test
description: test
confinement: strict

parts:
  part1:
    source: {0}
    plugin: autotools
"""

        for s in scenarios:
            with self.subTest(key=(s[1])):
                self.make_snapcraft_yaml(yaml_t.format(s[0]))
                c = internal_yaml.Config()

                self.assertTrue(
                    s[1] in c.build_tools,
                    '{} not found in {}'.format(s[1], c.build_tools))
Пример #5
0
    def test_config_runtime_environment_ld(self):
        # Place a few ld.so.conf files in supported locations. We expect the
        # contents of these to make it into the LD_LIBRARY_PATH.
        mesa_dir = os.path.join(self.snap_dir, 'usr', 'lib', 'my_arch', 'mesa')
        os.makedirs(mesa_dir)
        with open(os.path.join(mesa_dir, 'ld.so.conf'), 'w') as f:
            f.write('/mesa')

        mesa_egl_dir = os.path.join(self.snap_dir, 'usr', 'lib', 'my_arch',
                                    'mesa-egl')
        os.makedirs(mesa_egl_dir)
        with open(os.path.join(mesa_egl_dir, 'ld.so.conf'), 'w') as f:
            f.write('# Standalone comment\n')
            f.write('/mesa-egl')

        config = internal_yaml.Config()
        environment = config.snap_env()

        # Ensure that the LD_LIBRARY_PATH includes all the above paths
        paths = []
        for variable in environment:
            if 'LD_LIBRARY_PATH' in variable:
                these_paths = variable.split('=')[1].strip()
                paths.extend(these_paths.replace('"', '').split(':'))

        self.assertTrue(
            len(paths) > 0, 'Expected LD_LIBRARY_PATH to be in environment')

        expected = (os.path.join(self.snap_dir, i)
                    for i in ['mesa', 'mesa-egl'])
        for item in expected:
            self.assertTrue(
                item in paths,
                'Expected LD_LIBRARY_PATH to include "{}"'.format(item))
Пример #6
0
    def test_config_snap_environment_with_dependencies(self,
                                                       mock_get_dependencies):
        library_paths = {
            os.path.join(self.snap_dir, 'lib1'),
            os.path.join(self.snap_dir, 'lib2'),
        }
        mock_get_dependencies.return_value = library_paths
        config = internal_yaml.Config()

        for lib_path in library_paths:
            os.makedirs(lib_path)

        # Ensure that LD_LIBRARY_PATH is present and it contains the
        # extra dependency paths.
        paths = []
        for variable in config.snap_env():
            if 'LD_LIBRARY_PATH' in variable:
                these_paths = variable.split('=')[1].strip()
                paths.extend(these_paths.replace('"', '').split(':'))

        self.assertTrue(
            len(paths) > 0, 'Expected LD_LIBRARY_PATH to be in environment')

        expected = (os.path.join(self.snap_dir, i) for i in ['lib1', 'lib2'])
        for item in expected:
            self.assertTrue(
                item in paths,
                'Expected LD_LIBRARY_PATH ({!r}) to include {!r}'.format(
                    paths, item))
Пример #7
0
    def test_config_raises_on_missing_snapcraft_yaml(self):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)

        # no snapcraft.yaml
        with self.assertRaises(
                snapcraft.internal.yaml.SnapcraftYamlFileError) as raised:
            internal_yaml.Config()

        self.assertEqual(raised.exception.file, 'snapcraft.yaml')
Пример #8
0
    def test_config_snap_environment_with_no_library_paths(self):
        config = internal_yaml.Config()

        environment = config.snap_env()
        self.assertTrue(
            'PATH="{0}/bin:{0}/usr/bin:$PATH"'.format(self.snap_dir)
            in environment, 'Current PATH is {!r}'.format(environment))
        for e in environment:
            self.assertFalse('LD_LIBRARY_PATH' in e,
                             'Current environment is {!r}'.format(e))
Пример #9
0
    def test_two_snapcraft_yamls_cuase_error(self):
        open('snapcraft.yaml', 'w').close()
        open('.snapcraft.yaml', 'w').close()

        with self.assertRaises(EnvironmentError) as raised:
            internal_yaml.Config()

        self.assertEqual(
            str(raised.exception),
            "Found a 'snapcraft.yaml' and a '.snapcraft.yaml', "
            "please remove one")
Пример #10
0
    def test_config_stage_environment(self):
        paths = [
            os.path.join(self.stage_dir, 'lib'),
            os.path.join(self.stage_dir, 'lib', self.arch_triplet),
            os.path.join(self.stage_dir, 'usr', 'lib'),
            os.path.join(self.stage_dir, 'usr', 'lib', self.arch_triplet),
            os.path.join(self.stage_dir, 'include'),
            os.path.join(self.stage_dir, 'usr', 'include'),
            os.path.join(self.stage_dir, 'include', self.arch_triplet),
            os.path.join(self.stage_dir, 'usr', 'include', self.arch_triplet)
        ]
        for path in paths:
            os.makedirs(path)

        config = internal_yaml.Config()
        environment = config.stage_env()

        self.assertTrue('PATH="{0}/bin:{0}/usr/bin:$PATH"'.format(
            self.stage_dir) in environment)
        self.assertTrue(
            'LD_LIBRARY_PATH="$LD_LIBRARY_PATH:{stage_dir}/lib:'
            '{stage_dir}/usr/lib:{stage_dir}/lib/{arch_triplet}:'
            '{stage_dir}/usr/lib/{arch_triplet}"'.format(
                stage_dir=self.stage_dir, arch_triplet=self.arch_triplet)
            in environment, 'Current environment is {!r}'.format(environment))
        self.assertTrue(
            'CFLAGS="$CFLAGS -I{stage_dir}/include -I{stage_dir}/usr/include '
            '-I{stage_dir}/include/{arch_triplet} '
            '-I{stage_dir}/usr/include/{arch_triplet}"'.format(
                stage_dir=self.stage_dir, arch_triplet=self.arch_triplet)
            in environment, 'Current environment is {!r}'.format(environment))
        self.assertTrue(
            'CPPFLAGS="$CPPFLAGS -I{stage_dir}/include '
            '-I{stage_dir}/usr/include '
            '-I{stage_dir}/include/{arch_triplet} '
            '-I{stage_dir}/usr/include/{arch_triplet}"'.format(
                stage_dir=self.stage_dir, arch_triplet=self.arch_triplet)
            in environment, 'Current environment is {!r}'.format(environment))
        self.assertTrue(
            'CXXFLAGS="$CXXFLAGS -I{stage_dir}/include '
            '-I{stage_dir}/usr/include '
            '-I{stage_dir}/include/{arch_triplet} '
            '-I{stage_dir}/usr/include/{arch_triplet}"'.format(
                stage_dir=self.stage_dir, arch_triplet=self.arch_triplet)
            in environment, 'Current environment is {!r}'.format(environment))
        self.assertTrue(
            'LDFLAGS="$LDFLAGS -L{stage_dir}/lib -L{stage_dir}/usr/lib '
            '-L{stage_dir}/lib/{arch_triplet} '
            '-L{stage_dir}/usr/lib/{arch_triplet}"'.format(
                stage_dir=self.stage_dir, arch_triplet=self.arch_triplet)
            in environment, 'Current environment is {!r}'.format(environment))
        self.assertTrue('PERL5LIB={}/usr/share/perl5/'.format(self.stage_dir)
                        in environment)
Пример #11
0
    def test_visible_snapcraft_yaml_loads(self):
        self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: test
confinement: strict

parts:
  main:
    plugin: nil
""")

        internal_yaml.Config()
Пример #12
0
    def test_hidden_snapcraft_yaml_loads(self):
        self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: test
confinement: strict

parts:
  main:
    plugin: nil
""")

        os.rename('snapcraft.yaml', '.snapcraft.yaml')
        internal_yaml.Config()
Пример #13
0
    def test_config_snap_environment_with_dependencies_but_no_paths(
            self, mock_get_dependencies):
        library_paths = {
            os.path.join(self.snap_dir, 'lib1'),
            os.path.join(self.snap_dir, 'lib2'),
        }
        mock_get_dependencies.return_value = library_paths
        config = internal_yaml.Config()

        # Ensure that LD_LIBRARY_PATH is present, but is completey empty since
        # no library paths actually exist.
        for variable in config.snap_env():
            self.assertFalse(
                'LD_LIBRARY_PATH' in variable,
                'Expected no LD_LIBRARY_PATH (got {!r})'.format(variable))
Пример #14
0
    def test_invalid_yaml_invalid_app_names(self, mock_loadPlugin):
        invalid_app_names = [
            '',
            '-',
            '--',
            'a--a',
            'a-',
            'a ',
            ' a',
            'a a',
            '日本語',
            '한글',
            'ру́сский язы́к',
            'ໄຂ່​ອີ​ສ​ເຕີ້',
            ':a',
            'a:',
            'a:a',
            '_a',
            'a_',
            'a_a',
        ]

        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)

        for app_name in invalid_app_names:
            with self.subTest(key=app_name):
                self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: nothing
confinement: strict

apps:
  {!r}:
    command: foo

parts:
  part1:
    plugin: nil
""".format(app_name))
                with self.assertRaises(SnapcraftSchemaError) as raised:
                    internal_yaml.Config()

                self.assertRegex(
                    raised.exception.message,
                    "The 'apps' property does not match the required "
                    "schema.*")
Пример #15
0
    def test_config_loads_plugins(self, mock_get_part, mock_loadPlugin):
        self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: test

parts:
  part1:
    plugin: go
    stage-packages: [fswebcam]
""")
        internal_yaml.Config()
        mock_loadPlugin.assert_called_with('part1', 'go', {
            'stage-packages': ['fswebcam'],
            'stage': [], 'snap': [],
        })

        self.assertFalse(mock_get_part.called)
Пример #16
0
    def test_config_adds_extra_build_tools_when_cross_compiling(self):
        with unittest.mock.patch('platform.machine') as machine_mock:
            machine_mock.return_value = 'x86_64'
            project_options = snapcraft.ProjectOptions(target_deb_arch='armhf')

        yaml = """name: test
version: "1"
summary: test
description: test

parts:
  part1:
    plugin: nil
"""
        self.make_snapcraft_yaml(yaml)
        config = internal_yaml.Config(project_options)

        self.assertEqual(config.build_tools, ['gcc-arm-linux-gnueabihf'])
Пример #17
0
    def test_part_dependents(self):
        self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: test

parts:
  main:
    plugin: nil

  dependent:
    plugin: nil
    after: [main]
""")
        config = internal_yaml.Config()

        self.assertFalse(config.part_dependents('dependent'))
        self.assertEqual({'dependent'}, config.part_dependents('main'))
Пример #18
0
    def test_config_with_wiki_part_after(self, mock_get_part, mock_load):
        self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: test
confinement: strict

parts:
  part1:
    after:
      - part2wiki
    plugin: go
    stage-packages: [fswebcam]
""")

        def load_effect(*args, **kwargs):
            mock_part = unittest.mock.Mock()
            mock_part.code.build_packages = []
            mock_part.deps = []
            mock_part.name = args[0]

            return mock_part

        mock_load.side_effect = load_effect
        mock_get_part.return_value = {
            'plugin': 'go',
            'source': 'http://somesource'
        }

        project_options = snapcraft.ProjectOptions()

        internal_yaml.Config(project_options)

        call1 = unittest.mock.call('part1', 'go', {
            'stage': [],
            'snap': [],
            'stage-packages': ['fswebcam']
        }, project_options, self.part_schema)
        call2 = unittest.mock.call('part2wiki', 'go',
                                   {'source': 'http://somesource'},
                                   project_options, self.part_schema)

        mock_load.assert_has_calls([call1, call2])
        self.assertTrue(mock_get_part.called)
Пример #19
0
    def test_config_loads_part_from_wiki(self, mock_compose, mock_loadPlugin):
        self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: test

parts:
  part1:
    stage-packages: [fswebcam]
""")
        mock_compose.return_value = {
            'plugin': 'go',
            'source': 'http://source.tar.gz',
        }

        internal_yaml.Config()

        mock_loadPlugin.assert_called_with('part1', 'go', {
            'source': 'http://source.tar.gz', 'stage': [], 'snap': []})
Пример #20
0
    def test_config_has_no_extra_build_tools_when_not_cross_compiling(self):
        class ProjectOptionsFake(snapcraft.ProjectOptions):
            @property
            def is_cross_compiling(self):
                return False

        yaml = """name: test
version: "1"
summary: test
description: test

parts:
  part1:
    plugin: nil
"""
        self.make_snapcraft_yaml(yaml)
        config = internal_yaml.Config(ProjectOptionsFake())

        self.assertEqual(config.build_tools, [])
Пример #21
0
    def test_invalid_yaml_missing_description(self, mock_loadPlugin):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)

        self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
confinement: strict

parts:
  part1:
    plugin: go
    stage-packages: [fswebcam]
""")
        with self.assertRaises(SnapcraftSchemaError) as raised:
            internal_yaml.Config()

        self.assertEqual(raised.exception.message,
                         "'description' is a required property")
Пример #22
0
    def test_yaml_valid_app_names(self, mock_loadPlugin):
        valid_app_names = [
            '1',
            'a',
            'aa',
            'aaa',
            'aaaa',
            'Aa',
            'aA',
            '1a',
            'a1',
            '1-a',
            'a-1',
            'a-a',
            'aa-a',
            'a-aa',
            'a-b-c',
            '0a-a',
            'a-0a',
        ]

        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)

        for app_name in valid_app_names:
            with self.subTest(key=app_name):
                self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: nothing
confinement: strict

apps:
  {!r}:
    command: foo

parts:
  part1:
    plugin: nil
""".format(app_name))
                c = internal_yaml.Config()
                self.assertTrue(app_name in c.data['apps'])
Пример #23
0
    def test_invalid_yaml_invalid_name_as_number(self, mock_loadPlugin):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)

        self.make_snapcraft_yaml("""name: 1
version: "1"
summary: test
description: nothing

parts:
  part1:
    plugin: go
    stage-packages: [fswebcam]
""")
        with self.assertRaises(SnapcraftSchemaError) as raised:
            internal_yaml.Config()

        self.assertEqual(raised.exception.message,
                         "The 'name' property does not match the required "
                         "schema: 1 is not of type 'string'")
Пример #24
0
    def test_invalid_yaml_invalid_icon_extension(self, mock_loadPlugin):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)

        self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: test
icon: icon.foo

parts:
  part1:
    plugin: go
    stage-packages: [fswebcam]
""")
        with self.assertRaises(SnapcraftSchemaError) as raised:
            internal_yaml.Config()

        self.assertEqual(raised.exception.message,
                         "'icon' must be either a .png or a .svg")
Пример #25
0
    def test_config_composes_with_a_non_existent_remote_part(self):
        self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: test
confinement: strict

parts:
  non-existing-part:
    stage-packages: [fswebcam]
""")

        parts.update()

        with self.assertRaises(internal_yaml.SnapcraftLogicError) as raised:
            internal_yaml.Config()
        self.assertEqual(
            str(raised.exception),
            '{!r} is missing the `plugin` entry and is not defined in the '
            'current remote parts cache, try to run `snapcraft update` '
            'to refresh'.format('non-existing-part'))
Пример #26
0
    def test_invalid_yaml_invalid_name_chars(self, mock_loadPlugin):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)

        self.make_snapcraft_yaml("""name: myapp@me_1.0
version: "1"
summary: test
description: nothing

parts:
  part1:
    plugin: go
    stage-packages: [fswebcam]
""")
        with self.assertRaises(SnapcraftSchemaError) as raised:
            internal_yaml.Config()

        self.assertEqual(
            raised.exception.message,
            "The 'name' property does not match the required schema: "
            "'myapp@me_1.0' does not match '^[a-z0-9][a-z0-9+-]*$'")
Пример #27
0
    def test_tab_in_yaml(self, mock_loadPlugin):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)

        self.make_snapcraft_yaml("""name: test
version: "1"
\tsummary: test

parts:
  part1:
    plugin: go
    stage-packages: [fswebcam]
""")

        with self.assertRaises(SnapcraftSchemaError) as raised:
            internal_yaml.Config()

        self.assertEqual(
            raised.exception.message,
            'found character \'\\t\' that cannot start any token '
            'on line 2 of snapcraft.yaml')
Пример #28
0
    def test_config_uses_remote_part_from_after(self, mock_load):
        self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: test
confinement: strict

parts:
  part1:
    after:
      - curl
    plugin: go
    stage-packages: [fswebcam]
""")

        def load_effect(*args, **kwargs):
            mock_part = unittest.mock.Mock()
            mock_part.code.build_packages = []
            mock_part.deps = []
            mock_part.name = args[0]

            return mock_part

        mock_load.side_effect = load_effect

        project_options = snapcraft.ProjectOptions()

        parts.update()
        internal_yaml.Config(project_options)

        call1 = unittest.mock.call('part1', 'go', {
            'stage': [],
            'snap': [],
            'stage-packages': ['fswebcam']
        }, project_options, self.part_schema)
        call2 = unittest.mock.call('curl', 'autotools',
                                   {'source': 'http://curl.org'},
                                   project_options, self.part_schema)

        mock_load.assert_has_calls([call1, call2])
Пример #29
0
    def test_config_composes_with_remote_parts(self, mock_loadPlugin):
        self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: test
confinement: strict

parts:
  part1:
    stage-packages: [fswebcam]
""")

        parts.update()
        internal_yaml.Config()

        mock_loadPlugin.assert_called_with(
            'part1', 'go', {
                'source': 'http://source.tar.gz',
                'stage-packages': ['fswebcam'],
                'stage': [],
                'snap': []
            })
Пример #30
0
    def test_invalid_yaml_missing_icon(self, mock_loadPlugin):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)

        self.mock_path_exists.return_value = False

        self.make_snapcraft_yaml("""name: test
version: "1"
summary: test
description: test
icon: icon.png

parts:
  part1:
    plugin: go
    stage-packages: [fswebcam]
""")
        with self.assertRaises(SnapcraftSchemaError) as raised:
            internal_yaml.Config()

        self.assertEqual(raised.exception.message,
                         "Specified icon 'icon.png' does not exist")