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' })
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)
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()
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)
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)
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)
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)
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' } })
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)
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()
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)