def test_serialize_string(self, input_val, expected): serializer = Serializer() actual_serial = serializer._serialize_string(input_val) assert actual_serial == expected actual_deserial = serializer._deserialize_string(actual_serial) assert actual_deserial == (input_val or "")
def test_create_host_info(self): serializer = Serializer() foreground_color = Color(value=Color.CYAN) background_color = Color(value=Color.RED) cursor_position = Coordinates(x=1, y=2) window_position = Coordinates(x=3, y=4) cursor_size = 10 buffer_size = Size(height=10, width=20) window_size = Size(height=30, width=40) max_window_size = Size(height=50, width=60) max_physical_window_size = Size(height=70, width=80) window_title = "Random Window Title" ps_raw_ui = PSHostRawUserInterface( window_title, cursor_size, foreground_color, background_color, cursor_position, window_position, buffer_size, max_physical_window_size, max_window_size, window_size ) ps_ui = PSHostUserInterface(raw_ui=ps_raw_ui) ps_host = PSHost(None, None, False, None, None, ps_ui, None) host_info = HostInfo(host=ps_host) expected_xml = normalise_xml(self.HOST_XML) actual = serializer.serialize(host_info) actual_xml = normalise_xml(ET.tostring(actual)) assert_xml_diff(actual_xml, expected_xml)
def test_serialize_circualr_reference(self): serializer = Serializer() obj = GenericComplexObject() obj.types = [ "Microsoft.Exchange.Data.Directory.ADObjectId", "Microsoft.Exchange.Data.ObjectId", "System.Object" ] obj.to_string = "com" obj.adapted_properties = { "OrgHierarchyToIgnore": None, "IsDeleted": False, "Parent": None, "Depth": 0, "DistinguishedName": "DC=com", "IsRelativeDn": False, "DomainId": obj, "Name": "com", "SecurityIdentifierString": None } obj.property_sets.append("abc") obj.property_sets.append(obj) expected = \ '<Obj RefId="0"><TN RefId="0"><T>Microsoft.Exchange.Data.' \ 'Directory.ADObjectId</T><T>Microsoft.Exchange.Data.ObjectId</T>' \ '<T>System.Object</T></TN><ToString>com</ToString><S>abc</S>' \ '<Ref RefId="0" /><Props><I32 N="Depth">0</I32>' \ '<S N="DistinguishedName">DC=com</S>' \ '<Ref N="DomainId" RefId="0" /><B N="IsDeleted">false</B>' \ '<B N="IsRelativeDn">false</B><S N="Name">com</S>' \ '<Nil N="OrgHierarchyToIgnore" /><Nil N="Parent" />' \ '<Nil N="SecurityIdentifierString" /></Props></Obj>' actual = serializer.serialize(obj) actual_xml = to_string(ET.tostring(actual)) assert actual_xml == expected
def test_deserialize_circular_reference(self): serializer = Serializer() xml = '''<Obj N="DomainId" RefId="44"> <TN RefId="6"> <T>Microsoft.Exchange.Data.Directory.ADObjectId</T> <T>Microsoft.Exchange.Data.ObjectId</T> <T>System.Object</T> </TN> <ToString>com</ToString> <Props> <Nil N="OrgHierarchyToIgnore"/> <B N="IsDeleted">false</B> <Nil N="Parent"/> <I32 N="Depth">0</I32> <S N="DistinguishedName">DC=com</S> <B N="IsRelativeDn">false</B> <Ref N="DomainId" RefId="44"/> <S N="Name">com</S> <Nil N="SecurityIdentifierString"/> </Props> </Obj>''' actual = serializer.deserialize(xml) assert str(actual) == "com" assert str(actual.adapted_properties["DomainId"]) == "com" assert actual.adapted_properties["DomainId"].types == [ "Microsoft.Exchange.Data.Directory.ADObjectId", "Microsoft.Exchange.Data.ObjectId", "System.Object" ]
def test_parse_message(self): xml = """<Obj RefId="0"> <MS> <I64 N="ci">1</I64> <Obj N="mi" RefId="1"> <TN RefId="0"> <T>System.Management.Automation.Remoting.RemoteHostMethodId</T> <T>System.Enum</T> <T>System.ValueType</T> <T>System.Object</T> </TN> <ToString>ReadLine</ToString> <I32>11</I32> </Obj> <Obj N="mp" RefId="2"> <TN RefId="1"> <T>System.Collections.ArrayList</T> <T>System.Object</T> </TN> <LST/> </Obj> </MS> </Obj>""" serializer = Serializer() meta = ObjectMeta("Obj", object=RunspacePoolHostCall) actual = serializer.deserialize(xml, meta) assert actual.ci == 1 assert str(actual.mi) == "ReadLine" assert isinstance(actual.mi, HostMethodIdentifier) assert actual.mi.value == 11 assert actual.mp == []
def test_serialize_byte_string_py3(self): serialzier = Serializer() expected = "<BA>YWJj</BA>" actual = serialzier.serialize(b"abc") actual_xml = to_unicode(ET.tostring(actual)) expected_xml = to_unicode(expected) assert actual_xml == expected_xml
def test_serialize_secure_string_no_cipher(self): serializer = Serializer() with pytest.raises(SerializationError) as err: serializer._serialize_secure_string("") assert str( err.value ) == "Cannot generate secure string as cipher is not initialised"
def test_parse_message(self): xml = """<Obj RefId="11"> <MS> <S N="mr">Line read from the host</S> <I64 N="ci">1</I64> <Obj N="mi" RefId="12"> <TN RefId="4"> <T>System.Management.Automation.Remoting.RemoteHostMethodId</T> <T>System.Enum</T> <T>System.ValueType</T> <T>System.Object</T> </TN> <ToString>ReadLine</ToString> <I32>11</I32> </Obj> </MS> </Obj>""" serializer = Serializer() meta = ObjectMeta("Obj", object=RunspacePoolHostResponse) actual = serializer.deserialize(xml, meta) assert actual.ci == 1 assert actual.me is None assert str(actual.mi) == "ReadLine" assert isinstance(actual.mi, HostMethodIdentifier) assert actual.mi.value == 11 assert actual.mr == "Line read from the host"
def test_create_pipeline_multiple(self): serializer = Serializer() command1 = Command(protocol_version="2.2") command1.cmd = "Set-Variable" command1.is_script = False command1.use_local_scope = False command1.end_of_statement = True command1.args = [ CommandParameter(name="Name", value="var"), CommandParameter(name="Value", value="abc") ] command2 = Command(protocol_version="2.2") command2.cmd = "Get-Variable" command2.is_script = False command2.use_local_scope = False command2.args = [ CommandParameter(name="Name", value="var"), ] command3 = Command(protocol_version="2.2") command3.cmd = "Write-Output" command3.is_script = False command3.use_local_scope = False pipeline = Pipeline() pipeline.is_nested = False pipeline.commands = [command1, command2, command3] pipeline.redirect_err_to_out = False expected_xml = normalise_xml(self.PIPE_MULTIPLE) actual = serializer.serialize(pipeline) actual_xml = normalise_xml(ET.tostring(actual)) assert_xml_diff(actual_xml, expected_xml)
def test_parse_two_dimensional_array(self): serializer = Serializer() actual = serializer.deserialize(self.TWO_ARRAY, ObjectMeta("Obj", object=Array)) array = actual.array assert array == [[1, 2, 3], [4, 5, 6], [7, 8, 9]] assert actual.mae == [1, 2, 3, 4, 5, 6, 7, 8, 9] assert actual.mal == [3, 3]
def test_serialize_dynamic_obj(self): serializer = Serializer() expected = '<Obj RefId="0"><MS><S N="key">value</S></MS></Obj>' obj = GenericComplexObject() obj.extended_properties['key'] = "value" actual = serializer.serialize(obj) actual_xml = to_string(ET.tostring(actual)) assert actual_xml == expected
def test_parse_array(self): serializer = Serializer() actual = serializer.deserialize(self.SINGLE_ARRAY, ObjectMeta("Obj", object=Array)) array = actual.array assert array == [1, 2, 3] assert actual.mae == [1, 2, 3] assert actual.mal == [3]
def test_parse_buffer_cell(self): serializer = Serializer() actual = serializer.deserialize(normalise_xml(self.BUFFER_CELL), ObjectMeta("Obj", object=BufferCell)) assert actual.character == "A" assert actual.foreground_color.value == Color.CYAN assert actual.background_color.value == Color.GREEN assert actual.cell_type == BufferCellType.COMPLETE
def test_serialize_primitives(self, data, expected): serializer = Serializer() actual = serializer.serialize(data) actual_xml = to_unicode(ET.tostring(actual)) expected_xml = to_unicode(expected) assert actual_xml == expected_xml deserial_actual = serializer.deserialize(actual) assert deserial_actual == data
def test_deserialize_obj_no_types(self): serializer = Serializer() xml = '<Obj RefId="0"><MS><S N="key">value</S></MS></Obj>' actual = serializer.deserialize(xml) assert isinstance(actual, GenericComplexObject) assert actual.adapted_properties == {} assert actual.extended_properties == {"key": "value"} assert actual.property_sets == [] assert actual.to_string is None assert actual.types == []
def test_two_dimensional_create_array(self): serializer = Serializer() array = Array(array=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]) expected_xml = normalise_xml(self.TWO_ARRAY) actual = serializer.serialize(array) actual_xml = normalise_xml(ET.tostring(actual)) assert_xml_diff(actual_xml, expected_xml)
def test_parse_three_dimensional_array(self): serializer = Serializer() actual = serializer.deserialize(self.THREE_ARRAY, ObjectMeta("Obj", object=Array)) array = actual.array assert array == [ [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]] ] assert actual.mae == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] assert actual.mal == [2, 3, 4]
def test_serialize_primitives(self, data, expected): serializer = Serializer() actual = serializer.serialize(data) actual_xml = to_unicode(ET.tostring(actual)) expected_xml = to_unicode(expected) assert actual_xml == expected_xml deserial_actual = serializer.deserialize(actual) if isinstance(data, TaggedValue): data = data.value assert deserial_actual == data
def test_three_dimensional_create_array(self): serializer = Serializer() array = Array( array=[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]]) expected_xml = normalise_xml(self.THREE_ARRAY) actual = serializer.serialize(array) actual_xml = normalise_xml(ET.tostring(actual)) assert expected_xml == actual_xml
def test_serialize_list_as_ie(self): serializer = Serializer() data = [] data.append("0") data.append("1") data.append("2") expected = ('<Obj RefId="0"><TN RefId="0"><T>System.Object[]</T>' "<T>System.Array</T><T>System.Object</T></TN>" "<IE><S>0</S><S>1</S><S>2</S></IE></Obj>") actual = serializer.serialize(data, ListMeta("IE")) actual_xml = to_string(ET.tostring(actual)) assert actual_xml == expected
def test_create_buffer_cell(self): serializer = Serializer() buffer_cell = BufferCell(character="A", foreground_color=Color(value=Color.CYAN), background_color=Color(value=Color.GREEN), cell_type=BufferCellType.COMPLETE) expected_xml = normalise_xml(self.BUFFER_CELL) actual = serializer.serialize(buffer_cell) actual_xml = normalise_xml(ET.tostring(actual)) assert expected_xml == actual_xml
def test_parse_pipeline_multiple(self): serializer = Serializer() actual = serializer.deserialize(normalise_xml(self.PIPE_MULTIPLE), ObjectMeta("Obj", object=Pipeline)) assert actual.history is None assert actual.is_nested is False assert actual.redirect_err_to_out is False assert len(actual.commands) == 3 assert len(actual.commands[0].args) == 2 assert actual.commands[0].args[0].name == "Name" assert actual.commands[0].args[0].value == "var" assert actual.commands[0].args[1].name == "Value" assert actual.commands[0].args[1].value == "abc" assert actual.commands[0].cmd == "Set-Variable" assert actual.commands[0].end_of_statement is True assert actual.commands[0].is_script is False assert str(actual.commands[0].merge_debug) == "None" assert str(actual.commands[0].merge_error) == "None" assert str(actual.commands[0].merge_my_result) == "None" assert str(actual.commands[0].merge_previous) == "None" assert str(actual.commands[0].merge_verbose) == "None" assert str(actual.commands[0].merge_warning) == "None" assert actual.commands[0].use_local_scope is False assert len(actual.commands[1].args) == 1 assert actual.commands[1].args[0].name == "Name" assert actual.commands[1].args[0].value == "var" assert actual.commands[1].cmd == "Get-Variable" assert actual.commands[1].end_of_statement is False assert actual.commands[1].is_script is False assert str(actual.commands[1].merge_debug) == "None" assert str(actual.commands[1].merge_error) == "None" assert str(actual.commands[1].merge_my_result) == "None" assert str(actual.commands[1].merge_previous) == "None" assert str(actual.commands[1].merge_verbose) == "None" assert str(actual.commands[1].merge_warning) == "None" assert actual.commands[1].use_local_scope is False assert len(actual.commands[2].args) == 0 assert actual.commands[2].cmd == "Write-Output" assert actual.commands[2].end_of_statement is True assert actual.commands[2].is_script is False assert str(actual.commands[2].merge_debug) == "None" assert str(actual.commands[2].merge_error) == "None" assert str(actual.commands[2].merge_my_result) == "None" assert str(actual.commands[2].merge_previous) == "None" assert str(actual.commands[2].merge_verbose) == "None" assert str(actual.commands[2].merge_warning) == "None" assert actual.commands[2].use_local_scope is False
def test_serialize_list(self): serializer = Serializer() data = [] data.append("0") data.append("1") data.append("2") expected = ('<Obj RefId="0"><TN RefId="0"><T>System.Object[]</T>' "<T>System.Array</T><T>System.Object</T></TN>" "<LST><S>0</S><S>1</S><S>2</S></LST></Obj>") actual = serializer.serialize(data) actual_xml = to_string(ET.tostring(actual)) assert actual_xml == expected deserial_actual = serializer.deserialize(actual) assert deserial_actual == ["0", "1", "2"]
def sanitise_clixml(clixml): """ When running a powershell script in execute_cmd (WinRS), the stderr stream may contain some clixml. This method will clear it up and replace it with the error string it would represent. This isn't done by default on execute_cmd for various reasons but people can call it manually here if they like. :param clixml: The clixml to parse :return: A unicode code string of the decoded output """ output = to_unicode(clixml) if output.startswith("#< CLIXML"): # Strip off the '#< CLIXML\r\n' by finding the 2nd index of '<' output = output[clixml.index('<', 2):] element = ET.fromstring(output) namespace = element.tag.replace("Objs", "")[1:-1] errors = [] for error in element.findall("{%s}S[@S='Error']" % namespace): errors.append(error.text) output = Serializer()._deserialize_string("".join(errors)) return output
def test_deserialize_unknown_tag(self): serializer = Serializer() xml = '''<Obj N="Value" RefId="14"> <MS> <S N="T">System.Management.Automation.Host.Size</S> <Obj N="V" RefId="15"> <MS> <I32 N="height">50</I32> <I32 N="width">60</I32> </MS> </Obj> </MS> </Obj>''' actual = serializer.deserialize( xml, ObjectMeta("fake", object=GenericComplexObject)) assert actual == xml
def test_deserialize_obj_missing_prop(self): class SerialObject(ComplexObject): def __init__(self, **kwargs): super(SerialObject, self).__init__() self._types = ["System.Test", "System.Object"] self._extended_properties = (("man_prop", ObjectMeta("S", optional=False)), ) self.man_prop = kwargs.get("man_prop") serializer = Serializer() xml = '<Obj RefId="0"><TN RefId="0"><T>System.Test</T>' "<T>System.Object</T></TN><MS /></Obj>" with pytest.raises(SerializationError) as err: serializer.deserialize(xml, ObjectMeta("Obj", object=SerialObject)) assert str( err.value ) == "Mandatory return value for 'Unknown' was not found on object Unknown"
def test_deserialize_dynamic_obj_type_ref(self): serializer = Serializer() xml1 = ('<Obj RefId="0"><TN RefId="0">' "<T>System.Management.Automation.PSCustomObject</T>" "<T>System.Object</T></TN><ToString>to string value</ToString>" '<I32>1</I32><S>2</S><MS><S N="extended_key">extended</S></MS>' '<Props><S N="adapted_key">adapted</S></Props></Obj>') xml2 = ('<Obj RefId="2"><TNRef RefId="0" />' "<ToString>to string value 2</ToString>" '<I32>1</I32><S>2</S><MS><S N="extended_key">extended</S></MS>' '<Props><S N="adapted_key">adapted</S></Props></Obj>') serializer.deserialize(xml1) actual = serializer.deserialize(xml2, clear=False) assert str(actual) == "to string value 2" assert actual.types == [ "System.Management.Automation.PSCustomObject", "System.Object" ]
def test_create_array(self): serializer = Serializer() array = Array(array=[1, 2, 3]) expected_xml = normalise_xml(self.SINGLE_ARRAY) actual = serializer.serialize(array) actual_xml = normalise_xml(ET.tostring(actual)) assert_xml_diff(actual_xml, expected_xml) array.array = [4, 5, 6] expected_xml = normalise_xml(self.SINGLE_ARRAY2) actual = serializer.serialize(array) actual_xml = normalise_xml(ET.tostring(actual)) assert_xml_diff(actual_xml, expected_xml)
def test_parse_public_key_request(self): data = (b"\x02\x00\x00\x00" b"\x07\x00\x01\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"<S />") actual = Message.unpack(data, Serializer()) assert actual.message_type == MessageType.PUBLIC_KEY_REQUEST assert isinstance(actual.data, PublicKeyRequest)
def test_serialize_stack(self): # Python doesn't have a native type so serializing a list will reverse # the entries as a stack is last in first out. When deserializing we # don't reverse the entries as .pop(0) should return the last entry serializer = Serializer() data = [] data.append("0") data.append("1") data.append("2") expected = \ '<Obj RefId="0"><TN RefId="0"><T>System.Collections.Stack</T>' \ '<T>System.Object</T></TN>' \ '<STK><S>2</S><S>1</S><S>0</S></STK></Obj>' actual = serializer.serialize(data, StackMeta()) actual_xml = to_string(ET.tostring(actual)) assert actual_xml == expected deserial_actual = serializer.deserialize(actual) assert deserial_actual == ["2", "1", "0"]