def test_soap_input_header_order(self): """ Tests supports for input headers whose elements are provided in different order than that defined in rpc declaration _in_header parameter. """ server = ServerBase(self.app) initial_ctx = MethodContext(server, MethodContext.SERVER) initial_ctx.in_string = [ b'''<senv:Envelope xmlns:tns="tns" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:senv="http://schemas.xmlsoap.org/soap/envelope/"> <senv:Header> <wsa:MessageID>SomeMessageID</wsa:MessageID> <wsa:RelatesTo>SomeRelatesToID</wsa:RelatesTo> <wsa:Action>/SomeAction</wsa:Action> </senv:Header> <senv:Body> <tns:someRequest> <tns:status>OK</tns:status> </tns:someRequest> </senv:Body> </senv:Envelope>''' ] ctx, = server.generate_contexts(initial_ctx, in_string_charset='utf8') server.get_in_object(ctx) self.assertEquals(ctx.in_header[0], '/SomeAction') self.assertEquals(ctx.in_header[1], 'SomeMessageID') self.assertEquals(ctx.in_header[2], 'SomeRelatesToID')
def _dry_me(services, d, ignore_wrappers=False, complex_as=dict, just_ctx=False, just_in_object=False, validator=None, polymorphic=False): app = Application(services, 'tns', in_protocol=_DictDocumentChild( ignore_wrappers=ignore_wrappers, complex_as=complex_as, polymorphic=polymorphic, validator=validator, ), out_protocol=_DictDocumentChild( ignore_wrappers=ignore_wrappers, complex_as=complex_as, polymorphic=polymorphic), ) server = ServerBase(app) initial_ctx = MethodContext(server, MethodContext.SERVER) in_string = serializer.dumps(d, **dumps_kwargs) if not isinstance(in_string, bytes): in_string = in_string.encode('utf8') initial_ctx.in_string = [in_string] ctx, = server.generate_contexts(initial_ctx, in_string_charset='utf8') if not just_ctx: server.get_in_object(ctx) if not just_in_object: server.get_out_object(ctx) server.get_out_string(ctx) return ctx
def test_soap_input_header_order_and_missing(self): """ Test that header ordering logic also works when an input header element is missing. Confirm that it returns None for the missing parameter. """ server = ServerBase(self.app) initial_ctx = MethodContext(server, MethodContext.SERVER) initial_ctx.in_string = [ b'''<senv:Envelope xmlns:tns="tns" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:senv="http://schemas.xmlsoap.org/soap/envelope/"> <senv:Header> <wsa:MessageID>SomeMessageID</wsa:MessageID> <wsa:Action>/SomeAction</wsa:Action> </senv:Header> <senv:Body> <tns:someRequest> <tns:status>OK</tns:status> </tns:someRequest> </senv:Body> </senv:Envelope>''' ] ctx, = server.generate_contexts(initial_ctx, in_string_charset='utf8') server.get_in_object(ctx) self.assertEquals(ctx.in_header[0], '/SomeAction') self.assertEquals(ctx.in_header[1], 'SomeMessageID') self.assertEquals(ctx.in_header[2], None)
def test_decimal(self): d = decimal.Decimal('1e100') class SomeService(ServiceBase): @srpc(Decimal(120, 4), _returns=Decimal) def some_call(p): print p print type(p) assert type(p) == decimal.Decimal assert d == p return p app = Application([SomeService], "tns", in_protocol=XmlDocument(), out_protocol=XmlDocument()) server = ServerBase(app) initial_ctx = MethodContext(server) initial_ctx.in_string = [ '<some_call xmlns="tns"><p>%s</p></some_call>' % d ] ctx, = server.generate_contexts(initial_ctx) server.get_in_object(ctx) server.get_out_object(ctx) server.get_out_string(ctx) elt = etree.fromstring(''.join(ctx.out_string)) print etree.tostring(elt, pretty_print=True) target = elt.xpath('//tns:some_callResult/text()', namespaces=app.interface.nsmap)[0] assert target == str(d)
def test_soap_input_header(self): server = ServerBase(self.app) initial_ctx = MethodContext(server, MethodContext.SERVER) initial_ctx.in_string = [ b'''<senv:Envelope xmlns:tns="tns" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:senv="http://schemas.xmlsoap.org/soap/envelope/"> <senv:Header> <wsa:Action>/SomeAction</wsa:Action> <wsa:MessageID>SomeMessageID</wsa:MessageID> <wsa:RelatesTo>SomeRelatesToID</wsa:RelatesTo> </senv:Header> <senv:Body> <tns:someRequest> <tns:status>OK</tns:status> </tns:someRequest> </senv:Body> </senv:Envelope>''' ] ctx, = server.generate_contexts(initial_ctx, in_string_charset='utf8') server.get_in_object(ctx) self.assertEquals(ctx.in_header[0], '/SomeAction') self.assertEquals(ctx.in_header[1], 'SomeMessageID') self.assertEquals(ctx.in_header[2], 'SomeRelatesToID')
def test_attribute_ns(self): class a(ComplexModel): b = Unicode c = XmlAttribute(Unicode, ns="spam", attribute_of="b") class SomeService(ServiceBase): @srpc(_returns=a) def some_call(): return a(b="foo", c="bar") app = Application([SomeService], "tns", in_protocol=XmlDocument(), out_protocol=XmlDocument()) server = ServerBase(app) initial_ctx = MethodContext(server) initial_ctx.in_string = ['<some_call xmlns="tns"/>'] ctx, = server.generate_contexts(initial_ctx) server.get_in_object(ctx) server.get_out_object(ctx) server.get_out_string(ctx) elt = etree.fromstring(''.join(ctx.out_string)) target = elt.xpath('//s0:b', namespaces=app.interface.nsmap)[0] assert target.attrib['{%s}c' % app.interface.nsmap["s1"]] == "bar"
def test_mandatory_element_attributes(self): class C(ComplexModel): bar = XmlAttribute(M(Unicode)) class SomeService(ServiceBase): @srpc(C.customize(min_occurs=1), _returns=Unicode) def some_call(c): assert c is not None assert hasattr(c, 'foo') assert c.foo == 'hello' return c.foo app = Application( [SomeService], "tns", name="test_mandatory_element_attributes", in_protocol=XmlDocument(validator='lxml'), out_protocol=XmlDocument()) server = ServerBase(app) ctx = self._get_ctx(server, [ '<some_call xmlns="tns">' # no mandatory elements at all... '</some_call>' ]) self.assertRaises(SchemaValidationError, server.get_out_object, ctx) ctx = self._get_ctx(server, [ '<some_call xmlns="tns">' '<c>' # no mandatory elements here... '</c>' '</some_call>' ]) self.assertRaises(SchemaValidationError, server.get_out_object, ctx)
def test_mandatory_elements(self): class SomeService(ServiceBase): @srpc(M(Unicode), _returns=Unicode) def some_call(s): assert s == 'hello' return s app = Application([SomeService], "tns", name="test_mandatory_elements", in_protocol=XmlDocument(validator='lxml'), out_protocol=XmlDocument()) server = ServerBase(app) # Valid call with all mandatory elements in ctx = self._get_ctx(server, [ '<some_call xmlns="tns">' '<s>hello</s>' '</some_call>' ]) server.get_out_object(ctx) server.get_out_string(ctx) ret = etree.fromstring(''.join(ctx.out_string)).xpath( '//tns:some_call%s/text()' % RESULT_SUFFIX, namespaces=app.interface.nsmap)[0] assert ret == 'hello' # Invalid call ctx = self._get_ctx(server, [ '<some_call xmlns="tns">' # no mandatory elements here... '</some_call>' ]) self.assertRaises(SchemaValidationError, server.get_out_object, ctx)
def __init__(self, app, bookkeep=False, _clients=None): self.app = app self.transport = ServerBase(app) self.bookkeep = bookkeep self._clients = _clients if _clients is None: self._clients = {}
def test_parse_fault_response(self): """ Tests that a fault response from CPE is correctly parsed. """ # Example CPE->ACS fault response. Copied from: # http://djuro82.blogspot.com/2011/05/tr-069-cpe-provisioning.html cpe_string = b''' <soapenv:Envelope soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cwmp="urn:dslforum-org:cwmp-1-0"> <soapenv:Header> <cwmp:ID soapenv:mustUnderstand="1">1031422463</cwmp:ID> </soapenv:Header> <soapenv:Body> <soapenv:Fault> <faultcode>Client</faultcode> <faultstring>CWMP fault</faultstring> <detail> <cwmp:Fault> <FaultCode>9003</FaultCode> <FaultString>Invalid arguments</FaultString> <SetParameterValuesFault> <ParameterName>InternetGatewayDevice.WANDevice.1.WANConnectionDevice.3.WANPPPConnection.1.Password</ParameterName> <FaultCode>9003</FaultCode> <FaultString>Invalid arguments</FaultString> </SetParameterValuesFault> <SetParameterValuesFault> <ParameterName>InternetGatewayDevice.WANDevice.1.WANConnectionDevice.3.WANPPPConnection.1.Username</ParameterName> <FaultCode>9003</FaultCode> <FaultString>Invalid arguments</FaultString> </SetParameterValuesFault> </cwmp:Fault> </detail> </soapenv:Fault> </soapenv:Body> </soapenv:Envelope> ''' server = ServerBase(self.app) ctx = MethodContext(server, MethodContext.SERVER) ctx.in_string = [cpe_string] ctx, = server.generate_contexts(ctx) server.get_in_object(ctx) if ctx.in_error is not None: raise ctx.in_error # Calls function to receive and process message server.get_out_object(ctx) output_msg = ctx.out_object[0] self.assertEqual(type(output_msg), models.Fault) self.assertEqual(output_msg.FaultCode, 9003) self.assertEqual(output_msg.FaultString, 'Invalid arguments') self.assertEqual( output_msg.SetParameterValuesFault[1].ParameterName, 'InternetGatewayDevice.WANDevice.1.WANConnectionDevice.3.WANPPPConnection.1.Username', ) self.assertEqual(output_msg.SetParameterValuesFault[1].FaultCode, 9003) self.assertEqual( output_msg.SetParameterValuesFault[1].FaultString, 'Invalid arguments', )
def reinitialize(self): from spyne.server import ServerBase server = ServerBase(self) aux_memo = set() for s, d in self.interface.method_id_map.values(): if d.aux is not None and not id(d.aux) in aux_memo: d.aux.initialize(server) aux_memo.add(id(d.aux))
def deserialize_request_string(string, app): """Deserialize request string using in_protocol in application definition. Returns the corresponding native python object. """ server = ServerBase(app) initial_ctx = MethodContext(server) initial_ctx.in_string = [string] ctx = server.generate_contexts(initial_ctx)[0] server.get_in_object(ctx) return ctx.in_object
def test_invalid_input(self): class SomeService(ServiceBase): pass app = Application([SomeService], 'tns', in_protocol=JsonDocument(), out_protocol=JsonDocument()) server = ServerBase(app) initial_ctx = MethodContext(server, MethodContext.SERVER) initial_ctx.in_string = [b'{'] ctx, = server.generate_contexts(initial_ctx, in_string_charset='utf8') assert ctx.in_error.faultcode == 'Client.JsonDecodeError'
def test_invalid_input(self): class SomeService(Service): @srpc() def yay(): pass app = Application([SomeService], 'tns', in_protocol=MessagePackDocument(), out_protocol=MessagePackDocument()) server = ServerBase(app) initial_ctx = MethodContext(server, MethodContext.SERVER) initial_ctx.in_string = [b'\xdf'] # Invalid input ctx, = server.generate_contexts(initial_ctx) assert ctx.in_error.faultcode == 'Client.MessagePackDecodeError'
def test_invalid_input(self): class SomeService(ServiceBase): @srpc() def yay(): pass app = Application([SomeService], 'tns', in_protocol=YamlDocument(), out_protocol=YamlDocument()) server = ServerBase(app) initial_ctx = MethodContext(server) initial_ctx.in_string = ['{'] ctx, = server.generate_contexts(initial_ctx) assert ctx.in_error.faultcode == 'Client.YamlDecodeError'
def test_attribute_of_multi(self): class C(ComplexModel): e = Unicode(max_occurs='unbounded') a = XmlAttribute(Unicode, attribute_of="e") class SomeService(ServiceBase): @srpc(C, _returns=C) def some_call(c): assert c.e == ['e0', 'e1'] assert c.a == ['a0', 'a1'] return c app = Application([SomeService], "tns", name="test_attribute_of", in_protocol=XmlDocument(), out_protocol=XmlDocument()) server = ServerBase(app) initial_ctx = MethodContext(server) initial_ctx.method_request_string = '{test_attribute_of}some_call' initial_ctx.in_string = [ '<some_call xmlns="tns">' '<c>' '<e a="a0">e0</e>' '<e a="a1">e1</e>' '</c>' '</some_call>' ] ctx, = server.generate_contexts(initial_ctx) server.get_in_object(ctx) server.get_out_object(ctx) server.get_out_string(ctx) ret = etree.fromstring(''.join(ctx.out_string)).xpath( '//s0:e', namespaces=app.interface.nsmap) print(etree.tostring(ret[0], pretty_print=True)) print(etree.tostring(ret[1], pretty_print=True)) assert ret[0].text == "e0" assert ret[0].attrib['a'] == "a0" assert ret[1].text == "e1" assert ret[1].attrib['a'] == "a1"
def test_parse_empty_http(self): """ Test that empty HTTP message gets correctly mapped to 'EmptyHttp' function call """ cpe_string = b'' server = ServerBase(self.app) ctx = MethodContext(server, MethodContext.SERVER) ctx.in_string = [cpe_string] ctx, = server.generate_contexts(ctx) if ctx.in_error is not None: print('In error: %s' % ctx.in_error) self.assertEqual(ctx.in_error, None) self.assertEqual(ctx.function, AutoConfigServer.empty_http)
def test_attribute_of(self): class C(ComplexModel): a = Unicode b = XmlAttribute(Unicode, attribute_of="a") class SomeService(ServiceBase): @srpc(C, _returns=C) def some_call(c): assert c.a == 'a' assert c.b == 'b' return c app = Application([SomeService], "tns", name="test_attribute_of", in_protocol=XmlDocument(), out_protocol=XmlDocument()) server = ServerBase(app) initial_ctx = MethodContext(server) initial_ctx.in_string = [ '<some_call xmlns="tns">' '<c>' '<a b="b">a</a>' '</c>' '</some_call>' ] ctx, = server.generate_contexts(initial_ctx) server.get_in_object(ctx) server.get_out_object(ctx) server.get_out_string(ctx) ret = ''.join(ctx.out_string) print(ret) ret = etree.fromstring(ret) ret = ret.xpath('//s0:a', namespaces=app.interface.nsmap)[0] print(etree.tostring(ret, pretty_print=True)) assert ret.text == "a" assert ret.attrib['b'] == "b"
def test_xml_data(self): class C(ComplexModel): a = XmlData(Unicode) b = XmlAttribute(Unicode) class SomeService(ServiceBase): @srpc(C, _returns=C) def some_call(c): assert c.a == 'a' assert c.b == 'b' return c app = Application([SomeService], "tns", name="test_xml_data", in_protocol=XmlDocument(), out_protocol=XmlDocument()) server = ServerBase(app) initial_ctx = MethodContext(server, MethodContext.SERVER) initial_ctx.in_string = [ b'<some_call xmlns="tns">' b'<c b="b">a</c>' b'</some_call>' ] ctx, = server.generate_contexts(initial_ctx) server.get_in_object(ctx) server.get_out_object(ctx) server.get_out_string(ctx) print(ctx.out_string) pprint(app.interface.nsmap) ret = etree.fromstring(b''.join( ctx.out_string)).xpath('//tns:some_call' + RESULT_SUFFIX, namespaces=app.interface.nsmap)[0] print(etree.tostring(ret, pretty_print=True)) assert ret.text == "a" assert ret.attrib['b'] == "b"
def _dry_me(services, d, skip_depth=0, just_ctx=False, just_in_object=False, validator=None): app = Application( services, 'tns', in_protocol=_DictDocumentChild(validator=validator), out_protocol=_DictDocumentChild(skip_depth=skip_depth)) server = ServerBase(app) initial_ctx = MethodContext(server) initial_ctx.in_string = [serializer.dumps(d)] ctx, = server.generate_contexts(initial_ctx) if not just_ctx: server.get_in_object(ctx) if not just_in_object: server.get_out_object(ctx) server.get_out_string(ctx) return ctx
def test_parse_inform(self): cpe_string = b'''<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0"> <SOAP-ENV:Header> <cwmp:ID SOAP-ENV:mustUnderstand="1">CPE_1002</cwmp:ID> </SOAP-ENV:Header> <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <cwmp:Inform> <Event xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="cwmp:EventStruct[1]"> <EventStruct> <EventCode>0 BOOTSTRAP</EventCode> <CommandKey></CommandKey> </EventStruct> </Event> <MaxEnvelopes>1</MaxEnvelopes> <CurrentTime>1970-01-02T00:01:05.021239+00:00</CurrentTime> <RetryCount>2</RetryCount> </cwmp:Inform> </SOAP-ENV:Body> </SOAP-ENV:Envelope> ''' server = ServerBase(self.app) ctx = MethodContext(server, MethodContext.SERVER) ctx.in_string = [cpe_string] ctx, = server.generate_contexts(ctx) if ctx.in_error is not None: print('In error: %s' % ctx.in_error) self.assertEqual(ctx.in_error, None) server.get_in_object(ctx) self.assertEqual(ctx.in_object.Event.EventStruct[0].EventCode, '0 BOOTSTRAP')
def test_multiple_attribute_of_multiple_rpc(self): """ Tests the following: 1. Support for multiple attributes on a single element. 2. Correctness of attribute definition -- extension applied to correct 'attribute_of' element. 3. Another class/rpc with same element/attribute name works correctly. """ class CMA(ComplexModel): a = Unicode ab = XmlAttribute(Unicode, attribute_of="a") ac = XmlAttribute(Unicode, attribute_of="a") ad = XmlAttribute(Integer, attribute_of="a") b = Integer bb = XmlAttribute(Unicode, attribute_of="b") class CMB(ComplexModel): b = Integer bb = XmlAttribute(Unicode, attribute_of="b") class SomeService(ServiceBase): @srpc(CMA, _returns=CMA) def some_call(cma): assert cma.a == 'a' assert cma.ab == 'b' assert cma.ac == 'c' assert cma.ad == 5 assert cma.b == 9 assert cma.bb == "attrib bb" return cma @srpc(CMB, _returns=CMB) def another_call(cmb): assert cmb.b == 9 assert cmb.bb == 'attrib bb' return cmb app = Application([SomeService], "tns", name="test_multiple_attribute_of", in_protocol=XmlDocument(), out_protocol=XmlDocument()) server = ServerBase(app) # test some_call(CMA) initial_ctx = MethodContext(server) initial_ctx.in_string = [ '<some_call xmlns="tns">' '<cma>' '<a ab="b" ac="c" ad="5">a</a>' '<b bb="attrib bb">9</b>' '</cma>' '</some_call>' ] ctx, = server.generate_contexts(initial_ctx) server.get_in_object(ctx) server.get_out_object(ctx) server.get_out_string(ctx) ret = ''.join(ctx.out_string) print(ret) ret = etree.fromstring(ret) ret = ret.xpath('//s0:a', namespaces=app.interface.nsmap)[0] print(etree.tostring(ret, pretty_print=True)) assert ret.text == "a" assert ret.attrib['ab'] == "b" assert ret.attrib['ac'] == "c" assert int(ret.attrib['ad']) == 5 ret = ret.xpath('//s0:b', namespaces=app.interface.nsmap)[0] print(etree.tostring(ret, pretty_print=True)) assert ret.text == "9" assert ret.attrib['bb'] == "attrib bb" # test another_call(CMB) initial_ctx = MethodContext(server) initial_ctx.in_string = [ '<another_call xmlns="tns">' '<cmb>' '<b bb="attrib bb">9</b>' '</cmb>' '</another_call>' ] ctx, = server.generate_contexts(initial_ctx) server.get_in_object(ctx) server.get_out_object(ctx) server.get_out_string(ctx) ret = ''.join(ctx.out_string) print(ret) ret = etree.fromstring(ret) ret = ret.xpath('//s0:b', namespaces=app.interface.nsmap)[0] print(etree.tostring(ret, pretty_print=True)) assert ret.text == "9" assert ret.attrib['bb'] == "attrib bb"
def test_parse_hex_values(self): """ Test that non-utf-8 hex values can be parsed without error """ # Example TR-069 CPE->ACS RPC call. Copied from: # http://djuro82.blogspot.com/2011/05/tr-069-cpe-provisioning.html cpe_string = b''' <soapenv:Envelope soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cwmp="urn:dslforum-org:cwmp-1-0"> <soapenv:Header> <cwmp:ID soapenv:mustUnderstand="1">0_THOM_TR69_ID</cwmp:ID> </soapenv:Header> <soapenv:Body> <cwmp:Inform> <DeviceId> <Manufacturer>THOMSON</Manufacturer> <OUI>00147F</OUI> <ProductClass>SpeedTouch 780</ProductClass> <SerialNumber>CP0611JTLNW</SerialNumber> </DeviceId> <Event soap:arrayType="cwmp:EventStruct[04]"> <EventStruct> <EventCode>0 BOOTSTRAP</EventCode> <CommandKey></CommandKey> </EventStruct> <EventStruct> <EventCode>1 BOOT</EventCode> <CommandKey></CommandKey> </EventStruct> <EventStruct> <EventCode>2 PERIODIC</EventCode> <CommandKey></CommandKey> </EventStruct> <EventStruct> <EventCode>4 VALUE CHANGE</EventCode> <CommandKey></CommandKey> </EventStruct> </Event> <MaxEnvelopes>2</MaxEnvelopes> <CurrentTime>1970-01-01T00:01:09Z</CurrentTime> <RetryCount>05</RetryCount> <ParameterList soap:arrayType="cwmp:ParameterValueStruct[12]"> <ParameterValueStruct> <Name>InternetGatewayDevice.DeviceSummary</Name> <Value xsi:type="xsd:string"> \xff\xff\xff\xff\xff</Value> </ParameterValueStruct> </ParameterList> </cwmp:Inform> </soapenv:Body> </soapenv:Envelope> ''' server = ServerBase(self.app) ctx = MethodContext(server, MethodContext.SERVER) ctx.in_string = [cpe_string] ctx, = server.generate_contexts(ctx) if ctx.in_error is not None: print('In error: %s' % ctx.in_error) self.assertEqual(ctx.in_error, None) server.get_in_object(ctx)
def test_generate_set_parameter_values_string(self): """ Test that correct string is generated for SetParameterValues ACS->CPE request """ # Example ACS->CPE RPC call. Copied from: # http://djuro82.blogspot.com/2011/05/tr-069-cpe-provisioning.html # Following edits made: # - Change header ID value from 'null0' to 'null', to match magma # default ID expected_acs_string = b''' <soapenv:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <cwmp:ID soapenv:mustUnderstand="1">null</cwmp:ID> </soapenv:Header> <soapenv:Body> <cwmp:SetParameterValues> <ParameterList soap:arrayType="cwmp:ParameterValueStruct[4]"> <ParameterValueStruct> <Name>InternetGatewayDevice.ManagementServer.PeriodicInformEnable</Name> <Value xsi:type="xsd:boolean">1</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.ManagementServer.ConnectionRequestUsername</Name> <Value xsi:type="xsd:string">00147F-SpeedTouch780-CP0611JTLNW</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.ManagementServer.ConnectionRequestPassword</Name> <Value xsi:type="xsd:string">98ff55fb377bf724c625f60dec448646</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.ManagementServer.PeriodicInformInterval</Name> <Value xsi:type="xsd:unsignedInt">60</Value> </ParameterValueStruct> </ParameterList> <ParameterKey>null</ParameterKey> </cwmp:SetParameterValues> </soapenv:Body> </soapenv:Envelope> ''' request = models.SetParameterValues() request.ParameterList = \ models.ParameterValueList(arrayType='cwmp:ParameterValueStruct[4]') request.ParameterList.ParameterValueStruct = [] param = models.ParameterValueStruct() param.Name = 'InternetGatewayDevice.ManagementServer.PeriodicInformEnable' param.Value = models.anySimpleType(type='xsd:boolean') param.Value.Data = '1' request.ParameterList.ParameterValueStruct.append(param) param = models.ParameterValueStruct() param.Name = 'InternetGatewayDevice.ManagementServer.ConnectionRequestUsername' param.Value = models.anySimpleType(type='xsd:string') param.Value.Data = '00147F-SpeedTouch780-CP0611JTLNW' request.ParameterList.ParameterValueStruct.append(param) param = models.ParameterValueStruct() param.Name = 'InternetGatewayDevice.ManagementServer.ConnectionRequestPassword' param.Value = models.anySimpleType(type='xsd:string') param.Value.Data = '98ff55fb377bf724c625f60dec448646' request.ParameterList.ParameterValueStruct.append(param) param = models.ParameterValueStruct() param.Name = 'InternetGatewayDevice.ManagementServer.PeriodicInformInterval' param.Value = models.anySimpleType(type='xsd:unsignedInt') param.Value.Data = '60' request.ParameterList.ParameterValueStruct.append(param) request.ParameterKey = 'null' def side_effect(*args, **_kwargs): ctx = args[0] ctx.out_header = models.ID(mustUnderstand='1') ctx.out_header.Data = 'null' ctx.descriptor.out_message.Attributes.sub_name = request.__class__.__name__ return request self.p.stop() self.p = patch.object(AutoConfigServer, '_handle_tr069_message', Mock(side_effect=side_effect)) self.p.start() server = ServerBase(self.app) ctx = MethodContext(server, MethodContext.SERVER) ctx.in_string = [b''] ctx, = server.generate_contexts(ctx) server.get_in_object(ctx) if ctx.in_error is not None: raise ctx.in_error server.get_out_object(ctx) if ctx.out_error is not None: raise ctx.out_error server.get_out_string(ctx) xml_tree = XmlTree() match = xml_tree.xml_compare( xml_tree.convert_string_to_tree(b''.join(ctx.out_string)), xml_tree.convert_string_to_tree(expected_acs_string)) self.assertTrue(match)
def test_generate_get_parameter_values_string(self): """ Test that correct string is generated for SetParameterValues ACS->CPE request """ # Example ACS->CPE RPC call. Copied from: # http://djuro82.blogspot.com/2011/05/tr-069-cpe-provisioning.html # Following edits made: # - Change header ID value from 'null0' to 'null', to match magma # default ID expected_acs_string = b''' <soapenv:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <cwmp:ID soapenv:mustUnderstand="1">null</cwmp:ID> </soapenv:Header> <soapenv:Body> <cwmp:GetParameterValues> <ParameterNames soap:arrayType="xsd:string[1]"> <string>foo</string> </ParameterNames> </cwmp:GetParameterValues> </soapenv:Body> </soapenv:Envelope> ''' names = ['foo'] request = models.GetParameterValues() request.ParameterNames = models.ParameterNames() request.ParameterNames.arrayType = 'xsd:string[%d]' \ % len(names) request.ParameterNames.string = [] for name in names: request.ParameterNames.string.append(name) request.ParameterKey = 'null' def side_effect(*args, **_kwargs): ctx = args[0] ctx.out_header = models.ID(mustUnderstand='1') ctx.out_header.Data = 'null' ctx.descriptor.out_message.Attributes.sub_name = \ request.__class__.__name__ return AutoConfigServer._generate_acs_to_cpe_request_copy(request) self.p.stop() self.p = patch.object(AutoConfigServer, '_handle_tr069_message', side_effect=side_effect) self.p.start() server = ServerBase(self.app) ctx = MethodContext(server, MethodContext.SERVER) ctx.in_string = [b''] ctx, = server.generate_contexts(ctx) server.get_in_object(ctx) if ctx.in_error is not None: raise ctx.in_error server.get_out_object(ctx) if ctx.out_error is not None: raise ctx.out_error server.get_out_string(ctx) xml_tree = XmlTree() match = xml_tree.xml_compare( xml_tree.convert_string_to_tree(b''.join(ctx.out_string)), xml_tree.convert_string_to_tree(expected_acs_string)) self.assertTrue(match)
def test_handle_transfer_complete(self): """ Test that example TransferComplete RPC call can be parsed correctly, and response is correctly generated. """ # Example TransferComplete CPE->ACS RPC request/response. # Manually created. cpe_string = b''' <soapenv:Envelope soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cwmp="urn:dslforum-org:cwmp-1-0"> <soapenv:Header> <cwmp:ID soapenv:mustUnderstand="1">1234</cwmp:ID> </soapenv:Header> <soapenv:Body> <cwmp:TransferComplete> <CommandKey>Downloading stuff</CommandKey> <FaultStruct> <FaultCode>0</FaultCode> <FaultString></FaultString> </FaultStruct> <StartTime>2016-11-30T10:16:29Z</StartTime> <CompleteTime>2016-11-30T10:17:05Z</CompleteTime> </cwmp:TransferComplete> </soapenv:Body> </soapenv:Envelope> ''' expected_acs_string = b''' <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cwmp="urn:dslforum-org:cwmp-1-0"> <soapenv:Header> <cwmp:ID soapenv:mustUnderstand="1">1234</cwmp:ID> </soapenv:Header> <soapenv:Body> <cwmp:TransferCompleteResponse> </cwmp:TransferCompleteResponse> </soapenv:Body> </soapenv:Envelope> ''' self.p.stop() self.p.start() server = ServerBase(self.app) ctx = MethodContext(server, MethodContext.SERVER) ctx.in_string = [cpe_string] ctx, = server.generate_contexts(ctx) if ctx.in_error is not None: print('In error: %s' % ctx.in_error) self.assertEqual(ctx.in_error, None) server.get_in_object(ctx) self.assertEqual(ctx.in_error, None) server.get_out_object(ctx) self.assertEqual(ctx.out_error, None) output_msg = ctx.out_object[0] self.assertEqual(type(output_msg), models.TransferComplete) self.assertEqual(output_msg.CommandKey, 'Downloading stuff') self.assertEqual(output_msg.FaultStruct.FaultCode, 0) self.assertEqual(output_msg.FaultStruct.FaultString, '') self.assertEqual(output_msg.StartTime, datetime(2016, 11, 30, 10, 16, 29, tzinfo=timezone(timedelta(0)))) self.assertEqual(output_msg.CompleteTime, datetime(2016, 11, 30, 10, 17, 5, tzinfo=timezone(timedelta(0)))) server.get_out_string(ctx) self.assertEqual(ctx.out_error, None) xml_tree = XmlTree() match = xml_tree.xml_compare( xml_tree.convert_string_to_tree(b''.join(ctx.out_string)), xml_tree.convert_string_to_tree(expected_acs_string)) self.assertTrue(match)
def test_parse_inform_cavium(self): """ Test that example Inform RPC call can be parsed correctly from OC-LTE """ cpe_string = b'''<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0"> <SOAP-ENV:Header> <cwmp:ID SOAP-ENV:mustUnderstand="1">CPE_1002</cwmp:ID> </SOAP-ENV:Header> <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <cwmp:Inform> <DeviceId> <Manufacturer>Cavium, Inc.</Manufacturer> <OUI>000FB7</OUI> <ProductClass>Cavium eNB</ProductClass> <SerialNumber>10.18.104.79</SerialNumber> </DeviceId> <Event xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="cwmp:EventStruct[1]"> <EventStruct> <EventCode>0 BOOTSTRAP</EventCode> <CommandKey></CommandKey> </EventStruct> </Event> <MaxEnvelopes>1</MaxEnvelopes> <CurrentTime>1970-01-02T00:01:05.021239+00:00</CurrentTime> <RetryCount>2</RetryCount> <ParameterList xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="cwmp:ParameterValueStruct[15]"> <ParameterValueStruct> <Name>Device.DeviceInfo.HardwareVersion</Name> <Value xsi:type="xsd:string">1.0</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.DeviceInfo.SoftwareVersion</Name> <Value xsi:type="xsd:string">1.0</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.DeviceInfo.AdditionalHardwareVersion</Name> <Value xsi:type="xsd:string">1.0</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.DeviceInfo.AdditionalSoftwareVersion</Name> <Value xsi:type="xsd:string">1.0</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.DeviceInfo.ProvisioningCode</Name> <Value xsi:type="xsd:string">Cavium</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.ManagementServer.ParameterKey</Name> <Value xsi:type="xsd:string"></Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.ManagementServer.ConnectionRequestURL</Name> <Value xsi:type="xsd:string">http://192.88.99.253:8084/bucrhzjd</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.ManagementServer.UDPConnectionRequestAddress</Name> <Value xsi:type="xsd:string"></Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.ManagementServer.NATDetected</Name> <Value xsi:type="xsd:boolean">0</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.IP.Diagnostics.UDPEchoConfig.PacketsReceived</Name> <Value xsi:type="xsd:unsignedInt">0</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.IP.Diagnostics.UDPEchoConfig.PacketsResponded</Name> <Value xsi:type="xsd:unsignedInt">0</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.IP.Diagnostics.UDPEchoConfig.BytesReceived</Name> <Value xsi:type="xsd:unsignedInt">0</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.IP.Diagnostics.UDPEchoConfig.BytesResponded</Name> <Value xsi:type="xsd:unsignedInt">0</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.IP.Diagnostics.UDPEchoConfig.TimeFirstPacketReceived</Name> <Value xsi:type="xsd:dateTime">1969-12-31T16:00:00.000000+00:00</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>Device.IP.Diagnostics.UDPEchoConfig.TimeLastPacketReceived</Name> <Value xsi:type="xsd:dateTime">1969-12-31T16:00:00.000000+00:00</Value> </ParameterValueStruct> </ParameterList> </cwmp:Inform> </SOAP-ENV:Body> </SOAP-ENV:Envelope> ''' server = ServerBase(self.app) ctx = MethodContext(server, MethodContext.SERVER) ctx.in_string = [cpe_string] ctx, = server.generate_contexts(ctx) if ctx.in_error is not None: print('In error: %s' % ctx.in_error) self.assertEqual(ctx.in_error, None) server.get_in_object(ctx) self.assertEqual(ctx.in_object.DeviceId.OUI, '000FB7') self.assertEqual( ctx.in_object.Event.EventStruct[0].EventCode, '0 BOOTSTRAP') self.assertEqual(ctx.in_object.MaxEnvelopes, 1) self.assertEqual( ctx.in_object.ParameterList.ParameterValueStruct[1].Name, 'Device.DeviceInfo.SoftwareVersion') self.assertEqual( str(ctx.in_object.ParameterList.ParameterValueStruct[1].Value), '1.0')
def test_parse_inform(self): """ Test that example Inform RPC call can be parsed correctly """ # Example TR-069 CPE->ACS RPC call. Copied from: # http://djuro82.blogspot.com/2011/05/tr-069-cpe-provisioning.html cpe_string = b''' <soapenv:Envelope soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cwmp="urn:dslforum-org:cwmp-1-0"> <soapenv:Header> <cwmp:ID soapenv:mustUnderstand="1">0_THOM_TR69_ID</cwmp:ID> </soapenv:Header> <soapenv:Body> <cwmp:Inform> <DeviceId> <Manufacturer>THOMSON</Manufacturer> <OUI>00147F</OUI> <ProductClass>SpeedTouch 780</ProductClass> <SerialNumber>CP0611JTLNW</SerialNumber> </DeviceId> <Event soap:arrayType="cwmp:EventStruct[04]"> <EventStruct> <EventCode>0 BOOTSTRAP</EventCode> <CommandKey></CommandKey> </EventStruct> <EventStruct> <EventCode>1 BOOT</EventCode> <CommandKey></CommandKey> </EventStruct> <EventStruct> <EventCode>2 PERIODIC</EventCode> <CommandKey></CommandKey> </EventStruct> <EventStruct> <EventCode>4 VALUE CHANGE</EventCode> <CommandKey></CommandKey> </EventStruct> </Event> <MaxEnvelopes>2</MaxEnvelopes> <CurrentTime>1970-01-01T00:01:09Z</CurrentTime> <RetryCount>05</RetryCount> <ParameterList soap:arrayType="cwmp:ParameterValueStruct[12]"> <ParameterValueStruct> <Name>InternetGatewayDevice.DeviceSummary</Name> <Value xsi:type="xsd:string"> InternetGatewayDevice:1.1[] (Baseline:1, EthernetLAN:1, ADSLWAN:1, Bridging:1, Time:1, WiFiLAN:1)</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.DeviceInfo.SpecVersion</Name> <Value xsi:type="xsd:string">1.1</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.DeviceInfo.HardwareVersion</Name> <Value xsi:type="xsd:string">BANT-R</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.DeviceInfo.SoftwareVersion</Name> <Value xsi:type="xsd:string">6.2.35.0</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.DeviceInfo.ProvisioningCode</Name> <Value xsi:type="xsd:string"></Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.DeviceInfo.VendorConfigFile.1.Name</Name> <Value xsi:type="xsd:string">MyCompanyName</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.DeviceInfo.VendorConfigFile.1.Version</Name> <Value xsi:type="xsd:string"></Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.DeviceInfo.VendorConfigFile.1.Date</Name> <Value xsi:type="xsd:dateTime">0001-01-01T00:00:00</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.DeviceInfo.VendorConfigFile.1.Description</Name> <Value xsi:type="xsd:string">MyCompanyName</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.ManagementServer.ConnectionRequestURL</Name> <Value xsi:type="xsd:string">http://10.127.129.205:51005/</Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.ManagementServer.ParameterKey</Name> <Value xsi:type="xsd:string"></Value> </ParameterValueStruct> <ParameterValueStruct> <Name>InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ExternalIPAddress</Name> <Value xsi:type="xsd:string">10.127.129.205</Value> </ParameterValueStruct> </ParameterList> </cwmp:Inform> </soapenv:Body> </soapenv:Envelope> ''' server = ServerBase(self.app) ctx = MethodContext(server, MethodContext.SERVER) ctx.in_string = [cpe_string] ctx, = server.generate_contexts(ctx) if ctx.in_error is not None: print('In error: %s' % ctx.in_error) self.assertEqual(ctx.in_error, None) server.get_in_object(ctx) self.assertEqual(ctx.in_object.DeviceId.OUI, '00147F') self.assertEqual( ctx.in_object.Event.EventStruct[0].EventCode, '0 BOOTSTRAP') self.assertEqual( ctx.in_object.Event.EventStruct[2].EventCode, '2 PERIODIC') self.assertEqual(ctx.in_object.MaxEnvelopes, 2) self.assertEqual( ctx.in_object.ParameterList.ParameterValueStruct[1].Name, 'InternetGatewayDevice.DeviceInfo.SpecVersion') self.assertEqual( str(ctx.in_object.ParameterList.ParameterValueStruct[1].Value), '1.1')