def test_should_filter_directory_with_custom_replacer (self): def replacer (token, replacement): return replacement.upper() self.create_tmp_dir("VARIABLES.localhost") self.create_tmp_file(("VARIABLES.localhost", "SPAM"), "spam") self.create_tmp_file(("VARIABLES.localhost", "EGGS"), "eggs") self.create_tmp_file(("VARIABLES.localhost", "HAM"), "ham") self.create_tmp_dir("is24-config-localhost") self.create_tmp_file(("is24-config-localhost", "motd"), "Today we serve @@@SPAM@@@ and @@@EGGS@@@.") self.create_tmp_dir(("is24-config-localhost", "tomorrow")) self.create_tmp_file(("is24-config-localhost", "tomorrow", "motd"), "Tomorrow we serve @@@HAM@@@ and @@@EGGS@@@.") TokenReplacer.filter_directory(self.tmp_directory, self.abspath("VARIABLES.localhost"), replacer_function=replacer) self.ensure_file_contents(("is24-config-localhost", "motd"), "Today we serve SPAM and EGGS.") self.ensure_file_contents(("is24-config-localhost", "tomorrow", "motd"), "Tomorrow we serve HAM and EGGS.")
def test_should_not_filter_file_with_encoding_unknown_8bit(self, mock_get_size, mock_config): mock_get_size.return_value = 10 mock_config.return_value = 20 mock_token_replacer = Mock(TokenReplacer) mock_token_replacer._read_content_from_file.return_value = 'fake binary file content' mock_token_replacer._get_file_encoding.return_value = 'unknown-8bit' TokenReplacer.filter_file(mock_token_replacer, "binary.file") self.assertEqual(0, mock_token_replacer._perform_filtering_on_file.call_count)
def test_should_filter_directory_with_var_in_var(self): self.create_tmp_dir("VARIABLES.localhost") self.create_tmp_file(("VARIABLES.localhost", "FOO"), "@@@BAR@@@") self.create_tmp_file(("VARIABLES.localhost", "BAR"), "bar") self.create_tmp_dir("is24-config-localhost") self.create_tmp_file(("is24-config-localhost", "text"), "Hello @@@FOO@@@ and @@@BAR@@@.") TokenReplacer.filter_directory(self.tmp_directory, self.abspath("VARIABLES.localhost")) self.ensure_file_contents(("is24-config-localhost", "text"), "Hello bar and bar.")
def test_should_not_filter_file_with_encoding_unknown_8bit( self, mock_get_size, mock_config): mock_get_size.return_value = 10 mock_config.return_value = 20 mock_token_replacer = Mock(TokenReplacer) mock_token_replacer._read_content_from_file.return_value = 'fake binary file content' mock_token_replacer._get_file_encoding.return_value = 'unknown-8bit' TokenReplacer.filter_file(mock_token_replacer, "binary.file") self.assertEqual( 0, mock_token_replacer._perform_filtering_on_file.call_count)
def test_should_return_value_of_token_when_content_has_surrounding_white_spaces( self): self.assertEquals( "spam", TokenReplacer({ "SPAM": " spam\n" }).filter("@@@SPAM@@@"))
def test_should_replace_token_in_token(self): self.assertEquals( "foo", TokenReplacer({ "FOO": "foo", "BAR": "@@@FOO@@@" }).filter("@@@BAR@@@"))
def _test_should_return_value_of_replaced_token_when_content_is_token_reference_and_token_contains_special_characters( self): self.assertEquals( "#\\/@$%&", TokenReplacer({ "SPAM": "#\\/@$%&" }).filter("@@@SPAM@@@"))
def test_should_strip_whitespaces_and_newlines_from_token_files (self): self.create_tmp_file("SPAM", " spam") self.create_tmp_file("EGGS", "eggs\n") token_replacer = TokenReplacer.from_directory(self.tmp_directory) self.assertEquals({'SPAM': 'spam', 'EGGS': 'eggs'}, token_replacer.token_values)
def test_should_return_value_of_content_with_replaced_tokens_when_content_is_a_mixture_of_static_text_and_tokens( self): self.assertEquals( "You should eat more spam and eggs.", TokenReplacer({ "SPAM": "spam", "EGGS": "eggs" }).filter("You should eat more @@@SPAM@@@ and @@@EGGS@@@."))
def test_should_return_value_of_two_tokens_when_content_is_double_token( self): self.assertEquals( "spameggs", TokenReplacer({ "SPAM": "spam", "EGGS": "eggs" }).filter("@@@SPAM@@@@@@EGGS@@@"))
def test_should_return_token_replacer_for_existing_directory (self): self.create_tmp_file("SPAM", "spam") self.create_tmp_file("EGGS", "eggs") token_replacer = TokenReplacer.from_directory(self.tmp_directory) self.assertEquals({'SPAM': 'spam', 'EGGS': 'eggs'}, token_replacer.token_values)
def test_should_use_custom_replacer_function(self): def custom_replacer_function(token, value): return "<%s:%s>" % (token, value) self.assertEquals( "<spam:eggs>", TokenReplacer({ "spam": "eggs" }, custom_replacer_function).filter("@@@spam@@@"))
def _filter_tokens_in_config_viewer(self): def configviewer_token_replacer (token, replacement): filtered_replacement = replacement.rstrip() return '<strong title="%s">%s</strong>' % (token, filtered_replacement) token_replacer = TokenReplacer.filter_directory(self.config_viewer_host_dir, self.variables_dir, html_escape=True, replacer_function=configviewer_token_replacer) tokens_unused = set(token_replacer.token_values.keys()) - token_replacer.token_used path_to_unused_variables = os.path.join(self.config_viewer_host_dir, 'unused_variables.txt') self._write_file(path_to_unused_variables, '\n'.join(sorted(tokens_unused))) token_replacer.filter_file(path_to_unused_variables, html_escape=True)
def test_should_filter_directory (self): self.create_tmp_dir("VARIABLES.localhost") self.create_tmp_file(("VARIABLES.localhost", "SPAM"), "spam") self.create_tmp_file(("VARIABLES.localhost", "EGGS"), "eggs") self.create_tmp_file(("VARIABLES.localhost", "HAM"), "ham") self.create_tmp_dir("is24-config-localhost") self.create_tmp_file(("is24-config-localhost", "motd"), "Today we serve @@@SPAM@@@ and @@@EGGS@@@.") self.create_tmp_dir(("is24-config-localhost", "tomorrow")) self.create_tmp_file(("is24-config-localhost", "tomorrow", "motd"), "Tomorrow we serve @@@HAM@@@ and @@@EGGS@@@.") TokenReplacer.filter_directory(self.tmp_directory, self.abspath("VARIABLES.localhost")) self.ensure_file_contents(("is24-config-localhost", "motd"), "Today we serve spam and eggs.") self.ensure_file_contents(("is24-config-localhost", "tomorrow", "motd"), "Tomorrow we serve ham and eggs.")
def _filter_tokens_in_config_viewer(self): def configviewer_token_replacer(token, replacement): filtered_replacement = replacement.rstrip() return '<strong title="%s">%s</strong>' % (token, filtered_replacement) token_replacer = TokenReplacer.filter_directory(self.config_viewer_host_dir, self.variables_dir, html_escape=True, replacer_function=configviewer_token_replacer, thread_name=self.thread_name) tokens_unused = set(token_replacer.token_values.keys()) - token_replacer.token_used path_to_unused_variables = os.path.join(self.config_viewer_host_dir, 'unused_variables.txt') self._write_file(path_to_unused_variables, '\n'.join(sorted(tokens_unused))) token_replacer.filter_file(path_to_unused_variables, html_escape=True)
def test_should_filter_directory_with_unused_variables (self): self.create_tmp_dir("VARIABLES.localhost") self.create_tmp_file(("VARIABLES.localhost", "SPAM"), "spam") self.create_tmp_file(("VARIABLES.localhost", "EGGS"), "eggs") self.create_tmp_file(("VARIABLES.localhost", "UNUSED"), "unused variable") self.create_tmp_dir("is24-config-localhost") self.create_tmp_file(("is24-config-localhost", "motd"), "Today we serve @@@SPAM@@@ and @@@EGGS@@@.") replacer = TokenReplacer.filter_directory(self.tmp_directory, self.abspath("VARIABLES.localhost")) self.assertEqual(replacer.token_used, set(["SPAM","EGGS"]))
def _filter_tokens_in_rpm_sources(self): TokenReplacer.filter_directory(self.host_config_dir, self.variables_dir, thread_name=self.thread_name)
def test_should_not_replace_token_if_content_contains_invalid_token_reference( self): self.assertEquals("@@@SPAM@@", TokenReplacer({ "SPAM": "spam" }).filter("@@@SPAM@@"))
def build(self): LOGGER.info('%s: building configuration rpm(s) for host "%s"', self.thread_name, self.hostname) self.logger.info("Building config rpm for host %s revision %s", self.hostname, self.revision) if exists(self.host_config_dir): raise ConfigDirAlreadyExistsException('ERROR: "%s" exists already whereas I should be creating it now.' % self.host_config_dir) try: mkdir(self.host_config_dir) except Exception as exception: raise CouldNotCreateConfigDirException('Could not create host config directory "%s".' % self.host_config_dir, exception) overall_requires = [] overall_provides = [] overall_svn_paths = [] overall_exported = {} for segment in OVERLAY_ORDER: svn_paths, exported_paths, requires, provides = self._overlay_segment(segment) overall_exported[segment] = exported_paths overall_svn_paths += svn_paths overall_requires += requires overall_provides += provides self.logger.debug("Overall_exported: %s", str(overall_exported)) self.logger.info("Overall_requires: %s", str(overall_requires)) self.logger.info("Overall_provides: %s", str(overall_provides)) self.logger.debug("Overall_svn_paths: %s", str(overall_svn_paths)) if not exists(self.variables_dir): mkdir(self.variables_dir) self._write_dependency_file(overall_requires, self.rpm_requires_path, collapse_duplicates=True) self._write_dependency_file(overall_provides, self.rpm_provides_path, False) self._write_file(os.path.join(self.variables_dir, 'REVISION'), self.revision) rpm_name_variable_file = os.path.join(self.variables_dir, 'RPM_NAME') self.is_a_group_rpm = exists(rpm_name_variable_file) do_not_write_host_segment_variable = self.is_a_group_rpm self._save_segment_variables(do_not_write_host_segment_variable) if self.is_a_group_rpm: try: TokenReplacer.filter_directory(os.path.dirname(self.variables_dir), self.variables_dir, thread_name=self.thread_name, skip=False) except Exception as e: LOGGER.warning("Problem during preliminary filtering of variables for group {0}: {1}".format(self.hostname, e)) with open(rpm_name_variable_file) as f: self.rpm_name = f.read().rstrip() LOGGER.info('Host {0} will trigger group rpm build with name {1}'.format(self.hostname, self.rpm_name)) self.spec_file_path = os.path.join(self.host_config_dir, self.config_rpm_prefix + self.rpm_name + '.spec') self._write_file(os.path.join(self.variables_dir, 'INSTALL_PROTECTION_DEPENDENCY'), '') else: self._write_file(rpm_name_variable_file, self.hostname) self.rpm_name = self.hostname self._write_file(os.path.join(self.variables_dir, 'INSTALL_PROTECTION_DEPENDENCY'), 'hostname-@@@HOST@@@') repo_packages_regex = get_repo_packages_regex() self._write_dependency_file(overall_requires, os.path.join(self.variables_dir, 'RPM_REQUIRES_REPOS'), filter_regex=repo_packages_regex) self._write_dependency_file(overall_requires, os.path.join(self.variables_dir, 'RPM_REQUIRES_NON_REPOS'), filter_regex=repo_packages_regex, positive_filter=False) self._export_spec_file() self._save_log_entries_to_variable(overall_svn_paths) self._save_overlaying_to_variable(overall_exported) self._move_variables_out_of_rpm_dir() self._save_file_list() self._save_network_variables() patch_info = self._generate_patch_info() self._copy_files_for_config_viewer() # write patch info into variable and config viewer self._write_file(os.path.join(self.variables_dir, 'VARIABLES'), patch_info) self._write_file(os.path.join(self.config_viewer_host_dir, self.hostname + '.variables'), patch_info) self._filter_tokens_in_rpm_sources() if not is_config_viewer_only_enabled(): self._build_rpm_using_rpmbuild() LOGGER.debug('%s: writing configviewer data for host "%s"', self.thread_name, self.hostname) self._filter_tokens_in_config_viewer() self._write_revision_file_for_config_viewer() self._write_overlaying_for_config_viewer(overall_exported) self._remove_logger_handlers() self._clean_up() return self._find_rpms()
def test_should_return_unmodified_content_when_content_does_not_contain_token( self): self.assertEquals("spam", TokenReplacer().filter("spam"))
def test_should_raise_exception_when_token_to_filter_is_missing(self): self.assertRaises(MissingTokenException, TokenReplacer().filter, "@@@NOT_FOUND@@@")
def test_should_return_value_of_token_when_content_is_single_token(self): self.assertEquals("spam", TokenReplacer({ "SPAM": "spam" }).filter("@@@SPAM@@@"))
def _filter_tokens_in_rpm_sources(self): TokenReplacer.filter_directory(self.host_config_dir, self.variables_dir)