def test_substitution_in_component_files(self): model = Model( components=[ Component(name="server", provided_services=[Service("Awesome")], variables=[ Variable( name="memory", value_type=str, values=["1GB", "2GB"], realization=[ Substitution( targets=["server/Dockerfile", "server/server.cfg"], pattern="mem=XXX", replacements=["mem=1", "mem=2"]) ]) ], implementation=DockerFile("server/Dockerfile")) ], goals=Goals(services=[Service("Awesome")])) server = model.resolve("server") configuration = Configuration( model, instances = [ Instance(name="server_0", definition=server, configuration=[(server.variables[0], "2GB")]) ]) self.realize(configuration) self.assert_file_contains("config_1/images/server_0/Dockerfile", "mem=2") self.assert_file_contains("config_1/images/server_0/server.cfg", "mem=2")
def _parse_variable(self, component, name, data): path = [Keys.COMPONENTS, component, Keys.VARIABLES, name] value_type = None values = [] realization = [] for key, item in data.items(): if key == Keys.VALUES: if not isinstance(item, list) and not isinstance(item, dict): self.wrong_type(list, type(item), *(path + [key])) continue values = self._parse_values(item, path + [key]) elif key == Keys.TYPE: if not isinstance(item, str): self.wrong_type(str, type(item), *(path + [key])) continue value_type = item elif key == Keys.REALIZATION: for index, each in enumerate(item, 1): substitution = self._parse_substitution( component, name, index, each) realization.append(substitution) else: self._ignore(*(path + [key])) return Variable(name, value_type, values, realization)
def _parse_values(self, data, path): values = [] if isinstance(data, list): values = [each for each in data] elif isinstance(data, dict): minimum = None maximum = None coverage = None for key, item in data.items(): if key == Keys.RANGE: minimum = min(item) maximum = max(item) elif key == Keys.COVERAGE: if not isinstance(item, int): self._wrong_type(int, type(item), *(path + [key])) continue coverage = item else: self._ignore(*(path + [key])) if minimum is None or maximum is None: self._missing([Keys.RANGE], *path) elif not coverage: self._missing([Keys.COVERAGE], *path) else: values = Variable.cover(minimum, maximum, coverage) else: self._wrong_type(dict, type(item), *path) return values
def test_raises_error_when_no_match_if_found_in_target(self): """ See Issue #40 """ model = Model( components=[ Component(name="server", provided_services=[Service("Awesome")], variables=[ Variable( name="memory", value_type=str, values=["1GB", "2GB"], realization=[ Substitution( targets=["docker-compose.yml"], pattern="pattern that does not exist", replacements=["mem=1", "mem=2"]) ]) ], implementation=DockerFile("server/Dockerfile")) ], goals=Goals(services=[Service("Awesome")])) server = model.resolve("server") configuration = Configuration( model, instances = [ Instance(name="server_0", definition=server, configuration=[(server.variables[0], "2GB")]) ]) with self.assertRaises(Exception): self.realize(configuration)
def test_when_a_variable_has_no_value(self): self._components = [ Component(name="c1", provided_services=[Service("S1")], provided_features=[Feature("F1")], variables=[Variable("memory", str, [])]) ] self._validate_model() self._verify_errors(EmptyVariableDomain)
def setUp(self): start_over() self._context = Context() components = [ Component( "c1", provided_services=[Service("S1")], provided_features=[Feature("F1")], variables=[Variable("memory", str, values=["1GB", "2GB"])]) ] self._model = Model(components, Goals(services=[Service("S1")])) self._context.load_metamodel() self._context.load_model(self._model)
def test_succeeds_in_inner_component_files(self): """ See Issue #48 """ self.create_template_file( component="server", resource="src/config/settings.ini", content="parameter=XYZ") model = Model( components=[ Component(name="server", provided_services=[Service("Awesome")], variables=[ Variable( name="memory", value_type=str, values=["1GB", "2GB"], realization=[ Substitution( targets=["server/src/config/settings.ini"], pattern="parameter=XYZ", replacements=["parameter=1GB", "parameter=2GB"]) ]) ], implementation=DockerFile("server/Dockerfile")) ], goals=Goals(services=[Service("Awesome")])) server = model.resolve("server") configuration = Configuration( model, instances = [ Instance(name="server_0", definition=server, configuration=[(server.variables[0], "2GB")]) ]) self.realize(configuration) self.assert_file_contains( "config_1/images/server_0/src/config/settings.ini", "parameter=2GB")
def test_substitution_with_pattern_longer_than_replacement(self): """ See Issue 57 """ self.create_template_file(component="server", resource="config.ini", content=("value: This is a very very long pattern\n" "Here is the end\n")) model = Model( components=[ Component(name="server", provided_services=[Service("Awesome")], variables=[ Variable( name="config", value_type=str, values=["v1"], realization=[ Substitution( targets=["server/config.ini"], pattern="value: This is a very very long pattern", replacements=["value: v1"]) ]) ], implementation=DockerFile("server/Dockerfile")) ], goals=Goals(services=[Service("Awesome")])) server = model.resolve("server") configuration = Configuration( model, instances = [ Instance(name="server_0", definition=server, configuration=[(server.variables[0], "v1")]) ]) self.realize(configuration) self.assert_file_contains_exactly( "config_1/images/server_0/config.ini", ("value: v1\n" "Here is the end\n"))
def test_select_a_specifc_resource(self): self.create_template_file(component="server", resource="apache_config.ini") self.create_template_file(component="server", resource="nginx_config.ini") model = Model( components=[ Component(name="server", provided_services=[Service("Awesome")], variables=[ Variable( name="provider", value_type=str, values=["apache", "nginx"], realization=[ ResourceSelection( "server/config.ini", [ "server/apache_config.ini", "server/nginx_config.ini" ] ) ]) ], implementation=DockerFile("server/Dockerfile")) ], goals=Goals(services=[Service("Awesome")])) server = model.resolve("server") configuration = Configuration( model, instances = [ Instance(name="server_0", definition=server, configuration=[(server.variables[0], "nginx")]) ]) self.realize(configuration) self.assert_exists("config_1/images/server_0/config.ini") self.assert_does_not_exist("config_1/images/server_0/apache_config.ini")
def test_substitute_pattern_that_contains_regex_sensitive_character(self): """ See Issue #56 """ self.create_template_file(content="\"resolve\": \"^1.1.6\"") model = Model( components=[ Component(name="server", provided_services=[Service("Awesome")], variables=[ Variable( name="memory", value_type=str, values=["1GB", "2GB"], realization=[ Substitution( targets=["server/server.cfg"], pattern="\"resolve\": \"^1.1.6\"", replacements=["\"resolve\": 1", "\"resolve\": 2"]) ]) ], implementation=DockerFile("server/Dockerfile")) ], goals=Goals(services=[Service("Awesome")])) server = model.resolve("server") configuration = Configuration( model, instances = [ Instance(name="server_0", definition=server, configuration=[(server.variables[0], "2GB")]) ]) self.realize(configuration) self.assert_file_contains( "config_1/images/server_0/server.cfg", "\"resolve\": 2")
def test_given_a_coverage_way_above_the_maximum_coverage(self): values = Variable.cover(0, 6, 12) self._assertItemsEqual([0, 6], values)
def test_given_a_coverage_that_is_not_a_natural_divisor(self): values = Variable.cover(0, 6, 4) self._assertItemsEqual([0, 3, 6], values)
def test_given_the_minimum_coverage(self): values = Variable.cover(0, 6, 1) self._assertItemsEqual([0, 1, 2, 3, 4, 5, 6], values)
def test_given_the_maximum_coverage(self): values = Variable.cover(0, 6, 6) self.assertItemsEqual([0, 6], values)