Exemplo n.º 1
0
    def test_remote_layer(self, mcall, ph):
        # XXX: this test does pull the git repo in the response
        responses.add(responses.GET,
                      "https://juju.github.io/layer-index/"
                      "layers/basic.json",
                      body='''{
                      "id": "basic",
                      "name": "basic",
                      "repo":
                      "https://git.launchpad.net/~bcsaller/charms/+source/basic",
                      "summary": "Base layer for all charms"
                      }''',
                      content_type="application/json")
        bu = build.Builder()
        bu.log_level = "WARNING"
        bu.output_dir = "out"
        bu.series = "trusty"
        bu.name = "foo"
        bu.charm = "trusty/use-layers"
        bu.hide_metrics = True
        bu.report = False
        # remove the sign phase
        bu.PHASES = bu.PHASES[:-2]

        bu()
        base = path('out/trusty/foo')
        self.assertTrue(base.exists())

        # basics
        self.assertTrue((base / "README.md").exists())

        # show that we pulled charmhelpers from the basic layer as well
        mcall.assert_called_with(("pip3", "install",
                                  "--user", "--ignore-installed",
                                  mock.ANY), env=mock.ANY)
Exemplo n.º 2
0
    def test_wheelhouse(self, Process, mkdtemp, rmtree_p, ph):
        mkdtemp.return_value = '/tmp'
        bu = build.Builder()
        bu.log_level = "WARN"
        bu.output_dir = "out"
        bu.series = "trusty"
        bu.name = "foo"
        bu.charm = "trusty/whlayer"
        bu.hide_metrics = True
        bu.report = False
        bu.wheelhouse_overrides = self.dirname / 'wh-over.txt'

        # remove the sign phase
        bu.PHASES = bu.PHASES[:-2]
        with mock.patch("path.Path.mkdir_p"):
            with mock.patch("path.Path.files"):
                bu()
                Process.assert_any_call((
                    'bash', '-c', '. /tmp/bin/activate ;'
                    ' pip3 download --no-binary :all: '
                    '-d /tmp -r ' +
                    self.dirname / 'trusty/whlayer/wheelhouse.txt'))
                Process.assert_any_call((
                    'bash', '-c', '. /tmp/bin/activate ;'
                    ' pip3 download --no-binary :all: '
                    '-d /tmp -r ' +
                    self.dirname / 'wh-over.txt'))
Exemplo n.º 3
0
    def test_remote_interface(self):
        # XXX: this test does pull the git repo in the response
        responses.add(responses.GET,
                      "https://juju.github.io/layer-index/"
                      "interfaces/pgsql.json",
                      body='''{
                      "id": "pgsql",
                      "name": "pgsql4",
                      "repo":
                      "https://github.com/bcsaller/juju-relation-pgsql.git",
                      "summary": "Postgres interface"
                      }''',
                      content_type="application/json")
        bu = build.Builder()
        bu.log_level = "WARNING"
        bu.output_dir = "out"
        bu.series = "trusty"
        bu.name = "foo"
        bu.charm = "trusty/c-reactive"
        bu.hide_metrics = True
        bu.report = False
        bu()
        base = path('out/trusty/foo')
        self.assertTrue(base.exists())

        # basics
        self.assertTrue((base / "a").exists())
        self.assertTrue((base / "README.md").exists())
        # show that we pulled the interface from github
        init = base / "hooks/relations/pgsql/__init__.py"
        self.assertTrue(init.exists())
        main = base / "hooks/reactive/main.py"
        self.assertTrue(main.exists())
Exemplo n.º 4
0
 def test_invalid_layer(self):
     """Test that invalid metadata.yaml files get a BuildError exception."""
     builder = build.Builder()
     builder.log_level = "DEBUG"
     builder.output_dir = "out"
     builder.series = "trusty"
     builder.name = "invalid-charm"
     builder.charm = "trusty/invalid-layer"
     metadata = path("tests/trusty/invalid-layer/metadata.yaml")
     try:
         builder()
         self.fail('Expected Builder to throw an exception on invalid YAML')
     except BuildError as e:
         self.assertEqual(
             "Failed to process {0}. "
             "Ensure the YAML is valid".format(metadata.abspath()), str(e))
Exemplo n.º 5
0
    def test_pypi_installer(self, mcall):
        bu = build.Builder()
        bu.log_level = "WARN"
        bu.output_dir = "out"
        bu.series = "trusty"
        bu.name = "foo"
        bu.charm = "trusty/chlayer"
        bu.hide_metrics = True
        bu.report = False

        # remove the sign phase
        bu.PHASES = bu.PHASES[:-2]
        bu()
        mcall.assert_called_with(
            ("pip3", "install", "--user", "--ignore-installed", mock.ANY),
            env=mock.ANY)
Exemplo n.º 6
0
    def test_wheelhouse(self, Process, mkdtemp, rmtree_p, ph, pi, pv):
        build.tactics.WheelhouseTactic.per_layer = False
        mkdtemp.return_value = '/tmp'
        bu = build.Builder()
        bu.log_level = "WARN"
        bu.build_dir = self.build_dir
        bu.cache_dir = bu.build_dir / "_cache"
        bu.series = "trusty"
        bu.name = "whlayer"
        bu.charm = "layers/whlayer"
        bu.hide_metrics = True
        bu.report = False
        bu.wheelhouse_overrides = self.dirname / 'wh-over.txt'

        def _store_wheelhouses(args):
            filename = args[-1].split()[-1]
            if filename.endswith('.txt'):
                Process._wheelhouses.append(path(filename).lines(retain=False))
            return mock.Mock(return_value=mock.Mock(exit_code=0))

        Process._wheelhouses = []
        Process.side_effect = _store_wheelhouses

        # remove the sign phase
        bu.PHASES = bu.PHASES[:-2]
        with self.dirname:
            with mock.patch("path.Path.mkdir_p"):
                with mock.patch("path.Path.files"):
                    bu()
                    self.assertEqual(len(Process._wheelhouses), 1)
                    self.assertEqual(Process._wheelhouses[0], [
                        '# layers/whbase',
                        '# foo==1.0  # overridden by whlayer',
                        '# bar==1.0  # overridden by whlayer',
                        '# qux==1.0  # overridden by whlayer',
                        '',
                        '# whlayer',
                        'foo==2.0',
                        'git+https://github.com/me/bar#egg=bar',
                        '# qux==2.0  # overridden by --wheelhouse-overrides',
                        '',
                        '# --wheelhouse-overrides',
                        'git+https://github.com/me/qux#egg=qux',
                        '',
                    ])
Exemplo n.º 7
0
    def test_pypi_installer(self, mcall, ph, pi, pv):
        bu = build.Builder()
        bu.log_level = "WARN"
        bu.build_dir = self.build_dir
        bu.cache_dir = bu.build_dir / "_cache"
        bu.series = "trusty"
        bu.name = "foo"
        bu.charm = "layers/chlayer"
        bu.hide_metrics = True
        bu.report = False

        # remove the sign phase
        bu.PHASES = bu.PHASES[:-2]
        with self.dirname:
            bu()
        mcall.assert_called_with(
            ("pip3", "install", "--user", "--ignore-installed", mock.ANY),
            env=mock.ANY)
Exemplo n.º 8
0
    def test_version_tactic_with_existing_version_file(self, mcall, ph, pi, get_sha, read):
        bu = build.Builder()
        bu.log_level = "WARN"
        bu.output_dir = "out"
        bu.series = "trusty"
        bu.name = "foo"
        bu.charm = "trusty/chlayer"
        bu.hide_metrics = True
        bu.report = False

        # remove the sign phase
        bu.PHASES = bu.PHASES[:-2]
        with mock.patch.object(build.tactics, 'log') as log:
            bu()
            log.warn.assert_has_calls(
                [mock.call('version sha1 is out of update, new sha sha2 will be used!')],
                any_order=True)

        self.assertEqual((path(bu.output_dir) / 'trusty' / bu.name / 'version').text(), 'sha2')
Exemplo n.º 9
0
 def test_invalid_layer(self):
     # Test that invalid metadata.yaml files get a BuildError exception.
     builder = build.Builder()
     builder.log_level = "DEBUG"
     builder.build_dir = self.build_dir
     builder.cache_dir = builder.build_dir / "_cache"
     builder.series = "trusty"
     builder.name = "invalid-charm"
     builder.charm = "layers/invalid-layer"
     builder.no_local_layers = False
     metadata = path("tests/layers/invalid-layer/metadata.yaml")
     try:
         with self.dirname:
             builder()
         self.fail('Expected Builder to throw an exception on invalid YAML')
     except BuildError as e:
         self.assertEqual(
             "Failed to process {0}. "
             "Ensure the YAML is valid".format(metadata.abspath()), str(e))
Exemplo n.º 10
0
    def test_version_tactic_without_existing_version_file(self, mcall, ph, pi, get_sha):
        bu = build.Builder()
        bu.log_level = "WARN"
        bu.output_dir = "out"
        bu.series = "trusty"
        bu.name = "foo"
        bu.charm = "trusty/chlayer"
        bu.hide_metrics = True
        bu.report = False

        # ensure no an existing version file
        version_file = bu.charm / 'version'
        version_file.remove_p()

        # remove the sign phase
        bu.PHASES = bu.PHASES[:-2]
        bu()

        self.assertEqual(
            (path(bu.output_dir) / 'trusty' / bu.name / 'version').text(), 'fake sha')
Exemplo n.º 11
0
    def test_version_tactic_missing_cmd(self, ph, pi):
        bu = build.Builder()
        bu.log_level = "WARN"
        bu.build_dir = self.build_dir
        bu.cache_dir = bu.build_dir / "_cache"
        bu.series = "trusty"
        bu.name = "foo"
        bu.charm = "layers/chlayer"
        bu.hide_metrics = True
        bu.report = False

        # ensure no an existing version file
        version_file = bu.charm / 'version'
        version_file.remove_p()

        # remove the sign phase
        bu.PHASES = bu.PHASES[:-2]
        with self.dirname:
            bu()

        assert not (bu.target_dir / 'version').exists()
Exemplo n.º 12
0
    def test_version_tactic_without_existing_version_file(
            self, mcall, ph, pi, get_sha):
        bu = build.Builder()
        bu.log_level = "WARN"
        bu.build_dir = self.build_dir
        bu.cache_dir = bu.build_dir / "_cache"
        bu.series = "trusty"
        bu.name = "foo"
        bu.charm = "layers/chlayer"
        bu.hide_metrics = True
        bu.report = False

        # ensure no an existing version file
        version_file = bu.charm / 'version'
        version_file.remove_p()

        # remove the sign phase
        bu.PHASES = bu.PHASES[:-2]
        with self.dirname:
            bu()

        self.assertEqual((bu.target_dir / 'version').text(), 'fake sha')
Exemplo n.º 13
0
    def test_remote_layer(self, mcall):
        # XXX: this test does pull the git repo in the response
        responses.add(responses.GET,
                      "http://interfaces.juju.solutions/api/v1/layer/basic/",
                      body='''{
                      "id": "basic",
                      "name": "basic",
                      "repo":
                      "https://git.launchpad.net/~bcsaller/charms/+source/basic",
                      "_id": {
                          "$oid": "55a471959c1d246feae487e5"
                      },
                      "version": 1
                      }''',
                      content_type="application/json")
        bu = build.Builder()
        bu.log_level = "WARNING"
        bu.output_dir = "out"
        bu.series = "trusty"
        bu.name = "foo"
        bu.charm = "trusty/use-layers"
        bu.hide_metrics = True
        bu.report = False
        # remove the sign phase
        bu.PHASES = bu.PHASES[:-2]

        bu()
        base = path('out/trusty/foo')
        self.assertTrue(base.exists())

        # basics
        self.assertTrue((base / "README.md").exists())

        # show that we pulled charmhelpers from the basic layer as well
        mcall.assert_called_with(
            ("pip3", "install", "--user", "--ignore-installed", mock.ANY),
            env=mock.ANY)
Exemplo n.º 14
0
    def test_wheelhouse(self, Process, mkdtemp, rmtree_p, ph, pi, pv, sign):
        build.tactics.WheelhouseTactic.per_layer = False
        mkdtemp.return_value = '/tmp'
        bu = build.Builder()
        bu.log_level = "WARN"
        bu.build_dir = self.build_dir
        bu.cache_dir = bu.build_dir / "_cache"
        bu.series = "trusty"
        bu.name = "whlayer"
        bu.charm = "layers/whlayer"
        bu.hide_metrics = True
        bu.report = False
        bu.wheelhouse_overrides = self.dirname / 'wh-over.txt'

        def _store_wheelhouses(args):
            filename = args[-1].split()[-1]
            if filename.endswith('.txt'):
                Process._wheelhouses.append(path(filename).lines(retain=False))
            return mock.Mock(return_value=mock.Mock(exit_code=0))
        Process._wheelhouses = []
        Process.side_effect = _store_wheelhouses

        # remove the sign phase
        bu.PHASES = bu.PHASES[:-2]
        with self.dirname:
            with mock.patch("path.Path.mkdir_p"):
                with mock.patch("path.Path.files"):
                    bu()
                    self.assertEqual(len(Process._wheelhouses), 1)
                    # note that setuptools uses both hyphen and underscore, but
                    # that should be normalized so that they match
                    self.assertEqual(Process._wheelhouses[0], [
                        '# layers/whbase',
                        '# base-comment',
                        '# foo==1.0  # overridden by whlayer',
                        '# bar==1.0  # overridden by whlayer',
                        '# qux==1.0  # overridden by whlayer',
                        '# setuptools-scm<=1.17.0  # overridden by '
                        '--wheelhouse-overrides',
                        '',
                        '# whlayer',
                        '# git+https://github.com/me/baz#egg=baz  # comment',
                        'foo==2.0',
                        'git+https://github.com/me/bar#egg=bar',
                        '# qux==2.0  # overridden by --wheelhouse-overrides',
                        '',
                        '# --wheelhouse-overrides',
                        'git+https://github.com/me/qux#egg=qux',
                        'setuptools_scm>=3.0<=3.4.1',
                        '',
                    ])

        sign.return_value = 'signature'
        wh = build.tactics.WheelhouseTactic(path('wheelhouse.txt'),
                                            mock.Mock(directory=path('wh')),
                                            mock.Mock(url='charm'),
                                            mock.Mock())
        # package name gets normalized properly when checking _layer_refs
        wh._layer_refs['setuptools-scm'] = 'layer:foo'
        wh.tracked = {path('wh/setuptools_scm-1.17.0.tar.gz')}
        self.assertEqual(wh.sign(), {
            'wheelhouse.txt': ('charm',
                               'dynamic',
                               'signature'),
            'setuptools_scm-1.17.0.tar.gz': ('layer:foo',
                                             'dynamic',
                                             'signature'),
        })
Exemplo n.º 15
0
    def test_regenerate_inplace(self):
        # take a generated example where a base layer has changed
        # regenerate in place
        # make some assertions
        bu = build.Builder()
        bu.log_level = "WARNING"
        bu.output_dir = "out"
        bu.series = "trusty"
        bu.name = "foo"
        bu.charm = "trusty/b"
        bu.hide_metrics = True
        bu.report = False
        bu()
        base = path('out/trusty/foo')
        self.assertTrue(base.exists())

        # verify the 1st gen worked
        self.assertTrue((base / "a").exists())
        self.assertTrue((base / "README.md").exists())

        # now regenerate from the target
        with utils.cd("out/trusty/foo"):
            bu = build.Builder()
            bu.log_level = "WARNING"
            bu.output_dir = path(os.getcwd())
            bu.series = "trusty"
            # The generate target and source are now the same
            bu.name = "foo"
            bu.charm = "."
            bu.hide_metrics = True
            bu.report = False
            bu()
            base = bu.output_dir
            self.assertTrue(base.exists())

            # Check that the generated layer.yaml makes sense
            cy = base / "layer.yaml"
            config = yaml.load(cy.open())
            self.assertEquals(config["includes"],
                              ["trusty/a", "interface:mysql"])
            self.assertEquals(config["is"], "foo")

            # We can even run it more than once
            bu()
            cy = base / "layer.yaml"
            config = yaml.load(cy.open())
            self.assertEquals(config["includes"],
                              ["trusty/a", "interface:mysql"])
            self.assertEquals(config["is"], "foo")

            # We included an interface, we should be able to assert things about it
            # in its final form as well
            provides = base / "hooks/relations/mysql/provides.py"
            requires = base / "hooks/relations/mysql/requires.py"
            self.assertTrue(provides.exists())
            self.assertTrue(requires.exists())

            # and that we generated the hooks themselves
            for kind in ["joined", "changed", "broken", "departed"]:
                self.assertTrue((base / "hooks" /
                                 "mysql-relation-{}".format(kind)).exists())

            # and ensure we have an init file (the interface doesn't its added)
            init = base / "hooks/relations/mysql/__init__.py"
            self.assertTrue(init.exists())
Exemplo n.º 16
0
    def test_tester_layer(self):
        bu = build.Builder()
        bu.log_level = "WARNING"
        bu.output_dir = "out"
        bu.series = "trusty"
        bu.name = "foo"
        bu.charm = "trusty/tester"
        bu.hide_metrics = True
        bu.report = False
        remove_layer_file = self.dirname / 'trusty/tester/to_remove'
        remove_layer_file.touch()
        with mock.patch.object(build, 'log') as log:
            bu()
            log.warn.assert_called_with(
                'Please add a `repo` key to your layer.yaml, '
                'with a url from which your layer can be cloned.')
        base = path('out/trusty/foo')
        self.assertTrue(base.exists())

        # Verify ignore rules applied
        self.assertFalse((base / ".bzr").exists())

        # Metadata should have combined provides fields
        metadata = base / "metadata.yaml"
        self.assertTrue(metadata.exists())
        metadata_data = yaml.load(metadata.open())
        self.assertIn("shared-db", metadata_data['provides'])
        self.assertIn("storage", metadata_data['provides'])

        # Config should have keys but not the ones in deletes
        config = base / "config.yaml"
        self.assertTrue(config.exists())
        config_data = yaml.load(config.open())['options']
        self.assertIn("bind-address", config_data)
        self.assertNotIn("vip", config_data)
        self.assertIn("key", config_data)
        self.assertEqual(config_data["key"]["default"], None)
        # Issue #99 where strings lose their quotes in a charm build.
        self.assertIn("numeric-string", config_data)
        default_value = config_data['numeric-string']['default']
        self.assertEqual(default_value, "0123456789", "value must be a string")

        cyaml = base / "layer.yaml"
        self.assertTrue(cyaml.exists())
        cyaml_data = yaml.load(cyaml.open())
        self.assertEquals(cyaml_data['includes'], ['trusty/mysql'])
        self.assertEquals(cyaml_data['is'], 'foo')
        self.assertEquals(cyaml_data['options']['trusty/mysql']['qux'], 'one')

        self.assertTrue((base / "hooks/config-changed").exists())

        # Files from the top layer as overrides
        start = base / "hooks/start"
        self.assertTrue(start.exists())
        self.assertIn("Overridden", start.text())

        self.assertTrue((base / "README.md").exists())
        self.assertEqual("dynamic tactics", (base / "README.md").text())

        sigs = base / ".build.manifest"
        self.assertTrue(sigs.exists())
        data = json.load(sigs.open())
        self.assertEquals(data['signatures']["README.md"], [
            u'foo', "static", u'cfac20374288c097975e9f25a0d7c81783acdbc81'
            '24302ff4a731a4aea10de99'
        ])

        self.assertEquals(data["signatures"]['metadata.yaml'], [
            u'foo', "dynamic",
            u'0d7519db7301acb8efbd4f88bab5bc0a1b927842cffeab99404aa7a4dc03d17d'
        ])

        storage_attached = base / "hooks/data-storage-attached"
        storage_detaching = base / "hooks/data-storage-detaching"
        self.assertTrue(storage_attached.exists())
        self.assertTrue(storage_detaching.exists())
        self.assertIn("Hook: data", storage_attached.text())
        self.assertIn("Hook: data", storage_detaching.text())

        # confirm that files removed from a base layer get cleaned up
        self.assertTrue((base / 'to_remove').exists())
        remove_layer_file.remove()
        bu()
        self.assertFalse((base / 'to_remove').exists())
Exemplo n.º 17
0
    def test_tester_layer(self, pv):
        bu = build.Builder()
        bu.ignore_lock_file = True
        bu.log_level = "WARNING"
        bu.build_dir = self.build_dir
        bu.cache_dir = bu.build_dir / "_cache"
        bu.series = "trusty"
        bu.name = "foo"
        bu.charm = "layers/tester"
        bu.hide_metrics = True
        bu.report = False
        bu.charm_file = True
        remove_layer_file = self.dirname / 'layers/tester/to_remove'
        remove_layer_file.touch()
        charm_file = self.dirname / 'foo.charm'
        self.addCleanup(remove_layer_file.remove_p)
        self.addCleanup(charm_file.remove_p)
        with self.dirname:
            with mock.patch.object(build.builder, 'log') as log:
                with mock.patch.object(build.builder, 'repofinder') as rf:
                    rf.get_recommended_repo.return_value = None
                    bu()
                    log.warn.assert_called_with(
                        'Please add a `repo` key to your layer.yaml, '
                        'with a url from which your layer can be cloned.')
                    log.warn.reset_mock()
                    rf.get_recommended_repo.return_value = 'myrepo'
                    bu()
                    log.warn.assert_called_with(
                        'Please add a `repo` key to your layer.yaml, '
                        'e.g. repo: myrepo')
        base = bu.target_dir
        self.assertTrue(base.exists())
        self.assertTrue(charm_file.exists())
        with zipfile.ZipFile(charm_file, 'r') as zip:
            assert 'metadata.yaml' in zip.namelist()

        # Confirm that copyright file of lower layers gets renamed
        # and copyright file of top layer doesn't get renamed
        tester_copyright = (base / "copyright").text()
        mysql_copyright_path = base / "copyright.layer-mysql"
        self.assertIn("Copyright of tester", tester_copyright)
        self.assertTrue(mysql_copyright_path.isfile())

        # Verify ignore rules applied
        self.assertFalse((base / ".bzr").exists())
        self.assertEqual((base / "ignore").text(), "mysql\n")
        self.assertEqual((base / "exclude").text(), "test-base\n")
        self.assertEqual((base / "override-ignore").text(), "tester\n")
        self.assertEqual((base / "override-exclude").text(), "tester\n")
        self.assertFalse((base / "tests/00-setup").exists())
        self.assertFalse((base / "tests/15-configs").exists())
        self.assertTrue((base / "tests/20-deploy").exists())
        actions = yaml.safe_load((base / "actions.yaml").text())
        resources = yaml.safe_load((base / "resources.yaml").text())
        self.assertNotIn("test-base", actions)
        self.assertIn("mysql", actions)
        self.assertIn("tester", actions)
        self.assertIn("test-base", resources)
        self.assertNotIn("mysql", resources)
        self.assertIn("tester", resources)

        # Metadata should have combined provides fields
        metadata = base / "metadata.yaml"
        self.assertTrue(metadata.exists())
        metadata_data = yaml.safe_load(metadata.open())
        self.assertIn("shared-db", metadata_data['provides'])
        self.assertIn("storage", metadata_data['provides'])
        # The maintainer, maintainers values should only be from the top layer.
        self.assertIn("maintainer", metadata_data)
        self.assertEqual(metadata_data['maintainer'],
                         b"T\xc3\xa9sty T\xc3\xa9st\xc3\xa9r "
                         b"<t\xc3\xa9st\xc3\[email protected]>".decode('utf8'))
        self.assertNotIn("maintainers", metadata_data)
        # The tags list must be de-duplicated.
        self.assertEqual(metadata_data['tags'], ["databases"])
        self.assertEqual(metadata_data['series'], ['xenial', 'trusty'])

        # Config should have keys but not the ones in deletes
        config = base / "config.yaml"
        self.assertTrue(config.exists())
        config_data = yaml.safe_load(config.open())['options']
        self.assertIn("bind-address", config_data)
        self.assertNotIn("vip", config_data)
        self.assertIn("key", config_data)
        self.assertEqual(config_data["key"]["default"], None)
        # Issue #99 where strings lose their quotes in a charm build.
        self.assertIn("numeric-string", config_data)
        default_value = config_data['numeric-string']['default']
        self.assertEqual(default_value, "0123456789", "value must be a string")
        # Issue 218, ensure proper order of layer application
        self.assertEqual(config_data['backup_retention_count']['default'], 7,
                         'Config from layers was merged in wrong order')

        cyaml = base / "layer.yaml"
        self.assertTrue(cyaml.exists())
        cyaml_data = yaml.safe_load(cyaml.open())
        self.assertEquals(cyaml_data['includes'], ['layers/test-base',
                                                   'layers/mysql'])
        self.assertEquals(cyaml_data['is'], 'foo')
        self.assertEquals(cyaml_data['options']['mysql']['qux'], 'one')

        self.assertTrue((base / "hooks/config-changed").exists())

        # Files from the top layer as overrides
        start = base / "hooks/start"
        self.assertTrue(start.exists())
        self.assertIn("Overridden", start.text())

        # Standard hooks generated from template
        stop = base / "hooks/stop"
        self.assertTrue(stop.exists())
        self.assertIn("Hook: ", stop.text())

        self.assertTrue((base / "README.md").exists())
        self.assertEqual("dynamic tactics", (base / "README.md").text())

        self.assertTrue((base / "old_tactic").exists())
        self.assertEqual("processed", (base / "old_tactic").text())

        sigs = base / ".build.manifest"
        self.assertTrue(sigs.exists())
        data = json.load(sigs.open())
        self.assertEquals(data['signatures']["README.md"], [
            u'foo',
            "static",
            u'cfac20374288c097975e9f25a0d7c81783acdbc81'
            '24302ff4a731a4aea10de99'])

        self.assertEquals(data["signatures"]['metadata.yaml'], [
            u'foo',
            "dynamic",
            u'12c1f6fc865da0660f6dc044cca03b0244e883d9a99fdbdfab6ef6fc2fed63b7'
            ])

        storage_attached = base / "hooks/data-storage-attached"
        storage_detaching = base / "hooks/data-storage-detaching"
        self.assertTrue(storage_attached.exists())
        self.assertTrue(storage_detaching.exists())
        self.assertIn("Hook: data", storage_attached.text())
        self.assertIn("Hook: data", storage_detaching.text())

        # confirm that files removed from a base layer get cleaned up
        self.assertTrue((base / 'to_remove').exists())
        remove_layer_file.remove()
        with self.dirname:
            bu()
        self.assertFalse((base / 'to_remove').exists())
Exemplo n.º 18
0
 def test_environment_hide_metrics(self):
     # Setting the environment variable CHARM_HIDE_METRICS to a non-empty
     # value causes Builder.hide_metrics to be true.
     os.environ["CHARM_HIDE_METRICS"] = 'true'
     builder = build.Builder()
     self.assertTrue(builder.hide_metrics)
Exemplo n.º 19
0
 def test_default_no_hide_metrics(self):
     # In the absence of environment variables or command-line options,
     # Builder.hide_metrics is false.
     os.environ.pop("CHARM_HIDE_METRICS", None)
     builder = build.Builder()
     self.assertFalse(builder.hide_metrics)