Beispiel #1
0
    def test_load_config_with_default_provider(self):
        """
        Test Nulecule load_config with a default provider.
        """
        config = Config(answers={})

        params = [{
            "name": "key1",
            "default": "val1",
        }, {
            "name": "key3",
            "default": "val3"
        }, {
            "name": "provider",
            "default": "docker"
        }]

        graph = [{
            "name":
            "component1",
            "params": [{
                "name": "key1",
            }, {
                "name": "key2",
                "default": "val2"
            }],
            "artifacts": []
        }]

        n = Nulecule(id='some-id',
                     specversion='0.0.2',
                     metadata={},
                     graph=graph,
                     params=params,
                     basepath='some/path',
                     config=config)
        n.load_components()
        n.load_config(config)

        self.assertEqual(
            n.config.runtime_answers(), {
                'general': {
                    'namespace': 'default',
                    'provider': 'docker',
                    'key1': 'val1',
                    'key3': 'val3'
                },
                'component1': {
                    'key2': 'val2'
                }
            })

        self.assertEqual(
            n.components[0].config.context(scope=n.components[0].namespace), {
                'key3': 'val3',
                'key2': 'val2',
                'key1': 'val1',
                'provider': 'docker',
                'namespace': 'default'
            })
Beispiel #2
0
    def test_load_config_external_app(self):
        """Test load config for external app"""
        params = [{
            'name': 'key1',
            'description': 'key1'
        }, {
            'name': 'key2',
            'description': 'key2'
        }]
        initial_config = {
            'general': {
                'a': 'b',
                'key2': 'val2'
            },
            'some-app': {
                'key1': 'val1'
            }
        }
        config = Config(answers=initial_config)
        mock_nulecule = mock.Mock(name='nulecule',
                                  spec=Nulecule('some-id', '0.0.2', config, [],
                                                'some/path'))

        nc = NuleculeComponent('some-app', 'some/path', params=params)
        nc._app = mock_nulecule
        nc.config = config
        nc.load_config()

        mock_nulecule.load_config.assert_called_once_with(config=config,
                                                          ask=False,
                                                          skip_asking=False)
Beispiel #3
0
 def test_get_provider_failure(self):
     """
     Test if get_provider method when passed an invalid key raises an
     exception.
     """
     nb = NuleculeBase(params=[], basepath='', namespace='')
     # purposefully give the wrong provider key
     provider_key = u'mesos'
     nb.config = Config(answers={u'general': {u'provider': provider_key}})
     with self.assertRaises(NuleculeException):
         nb.get_provider()
Beispiel #4
0
    def test_render_for_local_app_with_missing_artifacts_for_provider(self):
        """
        Test rendering a Nulecule component with missing artifacts for a
        provider.
        """
        provider_key = 'some-provider'
        dryrun = False

        nc = NuleculeComponent(name='some-app', basepath='some/path')
        nc.config = Config()
        nc.artifacts = {'x': ['some-artifact']}

        self.assertRaises(NuleculeException, nc.render, provider_key, dryrun)
Beispiel #5
0
    def test_run(self):
        provider = 'docker'
        dryrun = False
        mock_component_1 = mock.Mock()
        mock_component_2 = mock.Mock()
        config = Config(answers={})

        n = Nulecule('some-id', '0.0.2', [{}], 'some/path', {}, config=config)
        n.components = [mock_component_1, mock_component_2]
        n.run(provider)

        mock_component_1.run.assert_called_once_with(provider, dryrun)
        mock_component_2.run.assert_called_once_with(provider, dryrun)
Beispiel #6
0
    def test_render_for_local_app_with_artifacts_for_provider(
            self, mock_render_artifact, mock_get_artifact_paths_for_provider):
        """Test rendering artifacts for a local Nulecule component"""
        provider_key = 'some-provider'
        dryrun = False
        expected_rendered_artifacts = [
            'some/path/.artifact1', 'some/path/.artifact2'
        ]
        mock_get_artifact_paths_for_provider.return_value = [
            'some/path/artifact1', 'some/path/artifact2'
        ]
        mock_render_artifact.side_effect = lambda path, context, provider: path.replace(
            'artifact', '.artifact')
        # mock_get_context.return_value = context

        nc = NuleculeComponent(name='some-app', basepath='some/path')
        nc.config = Config(answers={
            'general': {
                'key1': 'val1'
            },
            'some-provider': {
                'a': 'b'
            }
        })
        nc.artifacts = {
            'some-provider': ['artifact1', 'artifact2'],
            'x': ['foo']
        }
        nc.render(provider_key, dryrun)

        expected_context = {
            'key1': 'val1',
            'namespace': 'default',
            'provider': 'kubernetes'
        }
        mock_get_artifact_paths_for_provider.assert_called_once_with(
            provider_key)
        mock_render_artifact.assert_any_call('some/path/artifact1',
                                             expected_context, 'some-provider')
        mock_render_artifact.assert_any_call('some/path/artifact2',
                                             expected_context, 'some-provider')
        mock_get_artifact_paths_for_provider.assert_called_once_with(
            provider_key)
        self.assertEqual(nc.rendered_artifacts[provider_key],
                         expected_rendered_artifacts)
Beispiel #7
0
    def test_get_provider_success(self):
        """
        Test if get_provider method when passed a particular valid key returns
        the corresponding class.
        """
        nb = NuleculeBase(params=[], basepath='', namespace='')
        provider_key = u'openshift'
        # method `get_provider` will read from this config, we give it here
        # since we have neither provided it before nor it is auto-generated
        nb.config = Config(answers={u'general': {u'provider': provider_key}})

        return_provider = mock.Mock()
        # mocking return value of method plugin.getProvider,because it returns
        # provider class and that class gets called with values
        nb.plugin.getProvider = mock.Mock(return_value=return_provider)
        ret_provider_key, ret_provider = nb.get_provider()
        self.assertEqual(provider_key, ret_provider_key)
        return_provider.assert_called_with(
            {
                'provider': provider_key,
                'namespace': 'default'
            }, '', False)
Beispiel #8
0
    def test_load_config_local_app(self):
        """Test load config for local app"""
        params = [{
            'name': 'key1',
            'description': 'key1'
        }, {
            'name': 'key2',
            'description': 'key2'
        }]
        initial_config = {
            'general': {
                'a': 'b',
                'key2': 'val2'
            },
            'some-app': {
                'key1': 'val1'
            }
        }
        conf = Config(answers=initial_config)

        nc = NuleculeComponent('some-app',
                               'some/path',
                               params=params,
                               config=conf)
        nc.load_config()
        runtime_answers = nc.config.runtime_answers()
        self.assertEqual(
            runtime_answers, {
                'general': {
                    'a': 'b',
                    'key2': 'val2',
                    'provider': 'kubernetes',
                    'namespace': 'default'
                },
                'some-app': {
                    'key1': 'val1'
                }
            })
Beispiel #9
0
    def test_load_components(self, MockNuleculeComponent):
        graph = [{
            'name': 'app1',
            'source': 'docker://somecontainer',
            'params': []
        }, {
            'name': 'app2',
            'artifacts': [{
                'a': 'b'
            }]
        }]

        config = Config(answers={})

        n = Nulecule('some-id', '0.0.2', graph, 'some/path', config=config)
        n.load_components()

        MockNuleculeComponent.assert_any_call(graph[0]['name'], n.basepath,
                                              'somecontainer',
                                              graph[0]['params'], None, config)
        MockNuleculeComponent.assert_any_call(graph[1]['name'], n.basepath,
                                              None, graph[1].get('params'),
                                              graph[1].get('artifacts'),
                                              config)
Beispiel #10
0
def get_answers(nulecule_path):
    nulecule = Nulecule.load_from_path(nulecule_path)
    nulecule.config = Config()
    nulecule.load_config(skip_asking=True)
    return nulecule.config.runtime_answers()
Beispiel #11
0
    def __init__(self,
                 app_spec,
                 destination=None,
                 cli_answers=None,
                 answers_file=None,
                 answers_format=None):
        """
        init function for NuleculeManager. Sets a few instance variables.

        Args:
            app_spec: either a path to an unpacked nulecule app or a
                      container image name where a nulecule can be found
            destination: where to unpack a nulecule to if it isn't local
            cli_answers: some answer file values provided from cli args
            answers_file: the location of the answers file
            answers_format (str): File format for writing sample answers file
        """
        self.answers_format = answers_format or ANSWERS_FILE_SAMPLE_FORMAT
        self.answers_file = None  # The path to an answer file
        self.app_path = None  # The path where the app resides or will reside
        self.image = None  # The container image to pull the app from

        # Adjust app_spec, destination, and answer file paths if absolute.
        if os.path.isabs(app_spec):
            app_spec = Utils.get_real_abspath(app_spec)
        if destination and os.path.isabs(destination):
            destination = Utils.get_real_abspath(destination)
        if answers_file and os.path.isabs(answers_file):
            answers_file = Utils.get_real_abspath(answers_file)

        # If the user doesn't want the files copied to a permanent
        # location then he provides 'none'. If that is the case we'll
        # use a temporary directory
        if destination and destination.lower() == 'none':
            logger.debug("'none' destination requested. Using tmp dir")
            destination = tempfile.mkdtemp(prefix='atomicapp')

        # Determine if the user passed us an image or a path to an app
        if not os.path.exists(app_spec):
            self.image = app_spec
        else:
            self.app_path = app_spec

        # Doesn't really make much sense to provide an app path and destination,
        # but if they want to we'll simply just copy the files for them
        if self.app_path and destination:
            Utils.copy_dir(self.app_path, destination, update=True)
            self.app_path = destination

        # If the user provided an image, make sure we have a destination
        if self.image:
            if destination:
                self.app_path = destination
            else:
                self.app_path = Utils.getNewAppCacheDir(self.image)

        logger.debug("NuleculeManager init app_path: %s", self.app_path)
        logger.debug("NuleculeManager init image: %s", self.image)

        # Create the app_path if it doesn't exist yet
        if not os.path.isdir(self.app_path):
            os.makedirs(self.app_path)

        # Set where the main nulecule file should be
        self.main_file = os.path.join(self.app_path, MAIN_FILE)

        # Process answers.
        self.answers_file = answers_file
        self.config = Config(cli=cli_answers)