def _collect_from_instrcutions(self, current_instruction: InstructionWrapper, callpath: str = '') -> None: if callpath == '': callpath = str(current_instruction) else: callpath = f"{callpath}->{current_instruction}" # travel down to the leaf elements of the instruction tree # which are artefacts for child in current_instruction.instructionchildren: self._collect_from_instrcutions(child, callpath) # Artefacts do implement the method '_collect'. if '_collect' in dir(current_instruction.instruction): self._collect_and_document(current_instruction.instruction, callpath=callpath) # if the current instruction contains a "placeholdername" attribute this means # there is a placeholder for the global placeholder dictionary which needs to be # filled with the result of the current collector, so that following collectors # can use this information for their own collection process, like for example the # machine name. if current_instruction.placeholdername != '': Placeholder.update_placeholder( current_instruction.placeholdername, current_instruction.instruction.data[0].collecteddata) Collector._logger.info( f"Stored artefact data '{current_instruction.instruction.data}' as placeholder " f"'{current_instruction.placeholdername}'.") else: Collector._logger.debug(callpath)
def test_set_globalplaceholderfile(self): """Set the global placeholder file and initialize the placeholders with the file content""" with patch('businesslogic.placeholders.Placeholder._initialize_global_placeholders') as init_mock: Placeholder.set_globalplaceholderfile('./testfiles/test.txt') self.assertEqual(Placeholder._globalplaceholderfile, './testfiles/test.txt') init_mock.assert_called()
def test_set_globalplaceholderfile_with_testfile(self): """ Set the global placeholder file and initialize the placeholders with the file content with no mocking """ Placeholder.set_globalplaceholderfile(self._placeholder_test_file) self.assertEqual(Placeholder._globalplaceholderfile, self._placeholder_test_file)
def test_get_placeholder_casesensitive(self): """Should raise KeyError because of case insitivity""" Placeholder.set_globalplaceholderfile(self._placeholder_test_file) exisiting_placeholder = "client" nonexisting_placeholder = "Client" expected_value = "Sgt Mustman" self.assertEqual(Placeholder.get_placeholder(exisiting_placeholder), expected_value) with self.assertRaises(KeyError): Placeholder.get_placeholder(nonexisting_placeholder)
def test_update_placeolder_with_value_which_contains_placeholder(self): """ Should accept the placeholder. """ expected_placeholer = f"{Placeholder.PLACEHOLDER_START}test_placeholder{Placeholder.PLACEHOLDER_END}" expected_placeholder_value = "test_value" Placeholder.update_placeholder(placeholdername=expected_placeholer, placeholdervalue=expected_placeholder_value) actual_value = Placeholder._instruction_placeholders[expected_placeholer] self.assertEqual(expected_placeholder_value, actual_value)
def test_update_placeholder_with_new_placeholder(self): """ Should add the new placeholder to the global placeholders dicitionary. """ expected_placeholer = "test_placeholder" expected_placeholder_value = "test_value" Placeholder.update_placeholder(placeholdername=expected_placeholer, placeholdervalue=expected_placeholder_value) actual_value = Placeholder._instruction_placeholders[expected_placeholer] self.assertEqual(expected_placeholder_value, actual_value)
def test_get_placeholder_from_testfile(self): """ Should return content of test file if key is in the file. """ existing_placeholder = "client" expected_value = "Sgt Mustman" Placeholder.set_globalplaceholderfile(self._placeholder_test_file) actual_value = Placeholder.get_placeholder(existing_placeholder) self.assertEqual(actual_value, expected_value)
def _init_instructions(self, current: Element = None, parentinstruction=None, instructionid: int = 0): """ Parses the instructions xml file and initializes the artefact collectors in memory. Artefact xml elements need to have the attribute "module". If not, they are been ignored. :param current: Current xml element. Needed for recursive traversal. :param parentinstruction: Parent to be stored for current so later the collector can call back parent for context information. :param instructionid: Id of the current instruction which is an iterating integer starting with 0 for the first found collector. :return: object of type InstructionWrapper """ if current is None: current = self._get_first_instruction_element() currentinstruction = getattr( importlib.import_module( current.attributes[XmlParser.MODULE_ATTRIBUTE].nodeValue), current.tagName)(parent=parentinstruction, parameters=XmlParser._get_parameter_attributes( current.attributes)) currentinstruction.protocol = self._protocol placeholder_name = XmlParser._get_placeholder_name(current) # If there is a placeholder in the element store it for later use in the global placeholders if placeholder_name is not None and placeholder_name != "": Placeholder.update_placeholder( placeholder_name, f"{Placeholder.PLACEHOLDER_START}" f"{placeholder_name}" f"{Placeholder.PLACEHOLDER_END}") instructionwrapper = InstructionWrapper( instruction=currentinstruction, parentinstrutction=parentinstruction, instructionid=instructionid, placeholdername=placeholder_name) for child in current.childNodes: if type(child) is Element: instructionwrapper_child = self._init_instructions( current=child, parentinstruction=currentinstruction, instructionid=instructionid + 1) XmlParser._logger.debug( f"Adding '{instructionwrapper_child.instructionname}' with " f"id {instructionwrapper_child.instructionid} as child of " f"'{instructionwrapper.instructionname}' with id {instructionwrapper.instructionid}." ) instructionwrapper.addchild(instructionwrapper_child) return instructionwrapper
def test_set_globalplaceholderfile_invalid_json(self): """ Should not change _globalplaceholderfile :return: """ from businesslogic.placeholders import Placeholder expected_test_file = "./testfiles/test.txt" expected_file = Placeholder.GLOBAL_PLACEHOLDER_FILE_PATH with patch('businesslogic.placeholders.path.exists', MagicMock(return_value=True)): Placeholder.set_globalplaceholderfile(expected_test_file) self.assertEqual(expected_file, Placeholder._globalplaceholderfile)
def get_collector( cls, instructionsfile: str, examiner: str = '', placeholderfile: str = Placeholder.get_globalplaceholderfile(), protocollogfile: str = ''): Placeholder.set_globalplaceholderfile(placeholderfile) cls._logger.debug(f"Protocol log file: '{protocollogfile}'") protocol = LogFileProtocol(examiner, own_protocol_filename=protocollogfile) xmlparser = XmlParser(instructionsfile, protocol) collector = cls(parser=xmlparser, protocol=protocol) return collector
def test_update_placeholder_with_defined_placeholder(self): """ Should overwrite the placeholder already defined with the new value. """ expected_placeholer = "test_placeholder" expected_placeholder_value = "test_value" expected_placeholder_new_value = "test_value_new" Placeholder.update_placeholder(placeholdername=expected_placeholer, placeholdervalue=expected_placeholder_value) Placeholder.update_placeholder(placeholdername=expected_placeholer, placeholdervalue=expected_placeholder_new_value) actual_value = Placeholder._instruction_placeholders[expected_placeholer] self.assertEqual(expected_placeholder_new_value, actual_value)
def test_set_globalplaceholderfile(self): """ Should store file in _globalplaceholderfile Should call _initialize_global_placeholders() :return: """ from businesslogic.placeholders import Placeholder expected_file = "dummy" mock = MagicMock(return_value=None) with patch('businesslogic.placeholders.path.exists', MagicMock(return_value=True)): with patch('businesslogic.placeholders.Placeholder._initialize_global_placeholders', mock): Placeholder.set_globalplaceholderfile(expected_file) mock.assert_called_once() self.assertEqual(expected_file, Placeholder._globalplaceholderfile)
def test__call__should_replace_placeholder_in_string(self): """Using the @Placeholder decorator on a function returing a string should replace placeholders in that string with the values stored in the placeholder dictionary.""" Placeholder.set_globalplaceholderfile(self._placeholder_test_file) string_with_placeholder = f"This was it! {Placeholder.PLACEHOLDER_START}client{Placeholder.PLACEHOLDER_END} " \ f"had enough. 'This has to end now!', " \ f"{Placeholder.PLACEHOLDER_START}client{Placeholder.PLACEHOLDER_END} thought." expected_string = "This was it! Sgt Mustman had enough. 'This has to end now!', Sgt Mustman thought." @Placeholder def test_function(): return string_with_placeholder actual_string = test_function() self.assertEqual(actual_string, expected_string)
def test_replace_placeholders_no_placeholder(self): """ Should do nothing. """ expected_string = "This is a string with nothing" actual_string = Placeholder.replace_placeholders(expected_string) self.assertEqual(expected_string, actual_string)
def test_replace_placeholders_empty_string(self): """ Should do nothing. """ expected_string = "" actual_string = Placeholder.replace_placeholders(expected_string) self.assertEqual(expected_string, actual_string)
def test__get_placeholders_on_text_with_one_placeholder(self): """ Should return a Match object containing all matched placeholders. """ expected_text = "test_placeholder" text = f"{Placeholder.PLACEHOLDER_START}{expected_text}{Placeholder.PLACEHOLDER_END}" actual_matches = Placeholder._get_placeholders(text_to_check=text) self.assertEqual(expected_text, actual_matches[0])
def test__initialize_global_placeholders(self): """ Should initialize the global placeholders dictionary with placeholders from json file. """ expected_placeholders = { "examiner": "sho", "clienttask": "Finish the task at hand.", "client": "Sgt Mustman", "artefactdescription": "BrackBook Flair", "APIKey": "a3f2a8f1fff851cds90a0cd7aef46389", "FritzIP": "10.0.99.254", "FritzPort": "38999", "MyUrl": "fill me in" } Placeholder._initialize_global_placeholders() for ph in expected_placeholders.keys(): self.assertEqual(expected_placeholders[ph], Placeholder._instruction_placeholders[ph])
def test_replace_placeholders_unkwon_placeholder(self): """ Should do nothing. """ expected_string = f"This is a string with " \ f"{Placeholder.PLACEHOLDER_START}unkown{Placeholder.PLACEHOLDER_END}" actual_string = Placeholder.replace_placeholders(expected_string) self.assertEqual(expected_string, actual_string)
def test__get_placeholders_no_placeholder(self): """ Should return empty Matches :return: """ from businesslogic.placeholders import Placeholder expected_string = "string without placeholders" expected_matches = [] actual_matches = Placeholder._get_placeholders(expected_string) self.assertEqual(expected_matches, actual_matches)
def test__get_placeholders_on_text_with_three_placeholders(self): """ Should return a Match object containing three matched placeholders. """ expected_matches = ["Hello", "there", "fool"] text = f"{Placeholder.PLACEHOLDER_START}{expected_matches[0]}{Placeholder.PLACEHOLDER_END} " \ f"{Placeholder.PLACEHOLDER_START}{expected_matches[1]}{Placeholder.PLACEHOLDER_END} " \ f"{Placeholder.PLACEHOLDER_START}{expected_matches[2]}{Placeholder.PLACEHOLDER_END}" actual_matches = Placeholder._get_placeholders(text_to_check=text) self.assertEqual(expected_matches, actual_matches)
def test__get_placeholder_placeholder_with_whitespace_in_string(self): """ Should return empty Matches :return: """ from businesslogic.placeholders import Placeholder expected_string = "string one!@nested @! placeholder" expected_matches = [] actual_matches = Placeholder._get_placeholders(expected_string) self.assertEqual(expected_matches, actual_matches)
def test__get_placeholder_nested_placeholder(self): """ Should only return the nested placeholder :return: """ from businesslogic.placeholders import Placeholder expected_string = "string !@one!@nested@!@! placeholder" expected_matches = ['nested'] actual_matches = Placeholder._get_placeholders(expected_string) self.assertEqual(expected_matches, actual_matches)
def test__get_placeholders_three_placeholders(self): """ Should return Matches with the three provided placeholders :return: """ from businesslogic.placeholders import Placeholder expected_string = "string !@one@!, !@two@!, !@three@! placeholder" expected_matches = ['one', 'two', 'three'] actual_matches = Placeholder._get_placeholders(expected_string) self.assertEqual(expected_matches, actual_matches)
def test_get_metadata_with_metadata_with_placeholder(self): """ Should return the metadata value, but the placeholder is replaced with the correct placeholder value. :return: """ from businesslogic.placeholders import Placeholder expected_metadata = {"Metadata1": "!@placeholder@!"} expected_metadata_key = "Metadata1" expected_metadata_value = "placeholdervalue" Placeholder.update_placeholder( placeholdername="placeholder", placeholdervalue=expected_metadata_value) actual_metadata = CollectionMetaData(metadata=expected_metadata) actual_metadata_value = actual_metadata.get_metadata( expected_metadata_key) self.assertEqual(expected_metadata_value, actual_metadata_value)
def test_replace_placeholders(self): """ Should replace the placeholder inside the provided text, if the value for the placeholder has already been defined. """ string_with_placeholder = f"This is a string with " \ f"{Placeholder.PLACEHOLDER_START}placeholder{Placeholder.PLACEHOLDER_END}" placeholder_value = "Yabubabba!" Placeholder._instruction_placeholders["placeholder"] = placeholder_value expected_string = f"This is a string with {placeholder_value}" actual_string = Placeholder.replace_placeholders(string_with_placeholder) self.assertEqual(expected_string, actual_string)
"""
def cache_parameters(cls, attributes: UserDict = None) -> None: for attributename in attributes.keys(): attributevalue = Placeholder.replace_placeholders(attributes[attributename]) Placeholder.update_placeholder(attributename, attributevalue) SourceBase._logger.debug( f"Source: Cached source parameter '{attributename}'. Parameter value: '{attributevalue}'")
def test_get_globalplaceholerfile(self): """Return the default placeholder file, if no placeholder file has been provided.""" actual_placeholder_file = Placeholder.get_globalplaceholderfile() self.assertEqual(actual_placeholder_file, Placeholder.GLOBAL_PLACEHOLDER_FILE_PATH)
def setUp(self) -> None: Placeholder.GLOBAL_PLACEHOLDER_FILE_PATH = "./global_placeholders.json" Placeholder._initialize_global_placeholders()
def test_get_placeholder_with_nonexisting_key(self): """Should raise KeyError if the placeholder does not exist.""" with self.assertRaises(KeyError): Placeholder.get_placeholder('IDoNotExist')