Example #1
0
    def test_xml_validation_with_xsd(self):
        """Tests for XML validation with XSD. If lxml is not
        installed, this tests would be skipped."""
        def request_xsd():
            url_path = stats_httpd.XSD_URL_PATH
            url_path = urllib.parse.quote(url_path)
            self.client.putrequest('GET', url_path)
            self.client.endheaders()
            xsd_doc = self.client.getresponse()
            xsd_doc = lxml_etree.parse(xsd_doc)
            return lxml_etree.XMLSchema(xsd_doc)

        def request_xmldoc(path=''):
            url_path = '%s/%s' % (stats_httpd.XML_URL_PATH, path)
            url_path = urllib.parse.quote(url_path)
            self.client.putrequest('GET', url_path)
            self.client.endheaders()
            xml_doc = self.client.getresponse()
            return lxml_etree.parse(xml_doc)

        # request XSD and XML
        xsd = request_xsd()
        xml_doc = request_xmldoc()
        # do validation
        self.assertTrue(xsd.validate(xml_doc))

        # validate each paths in DUMMY_DATA
        for path in stats_httpd.item_name_list(DUMMY_DATA, ''):
            # request XML
            xml_doc = request_xmldoc(path)
            # do validation
            self.assertTrue(xsd.validate(xml_doc))
Example #2
0
 def check_XML_URL_PATH(path=''):
     url_path = '%s/%s' % (stats_httpd.XML_URL_PATH, path)
     url_path = urllib.parse.quote(url_path)
     self.client.putrequest('GET', url_path)
     self.client.endheaders()
     response = self.client.getresponse()
     self.assertEqual(response.getheader("Content-type"), "text/xml")
     self.assertGreater(int(response.getheader("Content-Length")), 0)
     self.assertEqual(response.status, 200)
     xml_doctype = response.readline().decode()
     xsl_doctype = response.readline().decode()
     self.assertGreater(len(xml_doctype), 0)
     self.assertGreater(len(xsl_doctype), 0)
     root = xml.etree.ElementTree.parse(response).getroot()
     self.assertGreater(root.tag.find('statistics'), 0)
     schema_loc = '{%s}schemaLocation' % XMLNS_XSI
     # check the path of XSD
     self.assertEqual(root.attrib[schema_loc],
                      stats_httpd.XSD_NAMESPACE + ' '
                      + stats_httpd.XSD_URL_PATH)
     # check the path of XSL
     self.assertTrue(xsl_doctype.startswith(
             '<?xml-stylesheet type="text/xsl" href="' +
             stats_httpd.XSL_URL_PATH
             + '"?>'))
     # check whether the list of 'identifier' attributes in
     # root is same as the list of item names in DUMMY_DATA
     id_list = [ elm.attrib['identifier'] for elm in root ]
     item_list = [ it for it in \
                       stats_httpd.item_name_list(DUMMY_DATA, path) \
                       if len(it.split('/')) > 1 ]
     self.assertEqual(id_list, item_list)
     for elem in root:
         attr = elem.attrib
         value = isc.cc.data.find(DUMMY_DATA, attr['identifier'])
         # No 'value' attribute should be found in the 'item'
         # element when datatype of the value is list or dict.
         if type(value) is list or type(value) is dict:
             self.assertFalse('value' in attr)
         # The value of the 'value' attribute should be checked
         # after casting it to string type if datatype of the
         # value is int or float. Because attr['value'] returns
         # string type even if its value is int or float.
         elif type(value) is int or type(value) is float:
             self.assertEqual(attr['value'], str(value))
         else:
             self.assertEqual(attr['value'], value)
Example #3
0
 def test_xml_handler(self):
     self.stats_httpd = MyStatsHttpd(get_availaddr())
     module_name = 'Dummy'
     stats_spec = \
         { module_name :
               [{
                     "item_name": "foo",
                     "item_type": "string",
                     "item_optional": False,
                     "item_default": "bar",
                     "item_description": "foo is bar",
                     "item_title": "Foo"
                     },
                {
                     "item_name": "foo2",
                     "item_type": "list",
                     "item_optional": False,
                     "item_default": [
                         {
                             "zonename" : "test1",
                             "queries.udp" : 1,
                             "queries.tcp" : 2
                             },
                         {
                             "zonename" : "test2",
                             "queries.udp" : 3,
                             "queries.tcp" : 4
                             }
                     ],
                     "item_title": "Foo bar",
                     "item_description": "Foo bar",
                     "list_item_spec": {
                         "item_name": "foo2-1",
                         "item_type": "map",
                         "item_optional": False,
                         "item_default": {},
                         "map_item_spec": [
                             {
                                 "item_name": "foo2-1-1",
                                 "item_type": "string",
                                 "item_optional": False,
                                 "item_default": "",
                                 "item_title": "Foo2 1 1",
                                 "item_description": "Foo bar"
                                 },
                             {
                                 "item_name": "foo2-1-2",
                                 "item_type": "integer",
                                 "item_optional": False,
                                 "item_default": 0,
                                 "item_title": "Foo2 1 2",
                                 "item_description": "Foo bar"
                                 },
                             {
                                 "item_name": "foo2-1-3",
                                 "item_type": "integer",
                                 "item_optional": False,
                                 "item_default": 0,
                                 "item_title": "Foo2 1 3",
                                 "item_description": "Foo bar"
                                 }
                             ]
                         }
                     }]
           }
     stats_data = \
         { module_name : { 'foo':'bar',
                       'foo2': [
                         {
                             "foo2-1-1" : "bar1",
                             "foo2-1-2" : 10,
                             "foo2-1-3" : 9
                             },
                         {
                             "foo2-1-1" : "bar2",
                             "foo2-1-2" : 8,
                             "foo2-1-3" : 7
                             }
                         ] } }
     self.stats_httpd.get_stats_spec = lambda x,y: stats_spec
     self.stats_httpd.get_stats_data = lambda x,y: stats_data
     xml_string = self.stats_httpd.xml_handler()
     stats_xml = xml.etree.ElementTree.fromstring(xml_string)
     schema_loc = '{%s}schemaLocation' % XMLNS_XSI
     self.assertEqual(stats_xml.attrib[schema_loc],
                      stats_httpd.XML_ROOT_ATTRIB['xsi:schemaLocation'])
     stats_data = stats_data[module_name]
     stats_spec = stats_spec[module_name]
     names = stats_httpd.item_name_list(stats_data, '')
     for i in range(0, len(names)):
         self.assertEqual('%s/%s' % (module_name, names[i]), stats_xml[i].attrib['identifier'])
         value = isc.cc.data.find(stats_data, names[i])
         if type(value) is int:
             value = str(value)
         if type(value) is dict or type(value) is list:
             self.assertFalse('value' in stats_xml[i].attrib)
         else:
             self.assertEqual(value, stats_xml[i].attrib['value'])
         self.assertEqual(module_name, stats_xml[i].attrib['owner'])
         self.assertEqual(urllib.parse.quote('%s/%s/%s' % (stats_httpd.XML_URL_PATH,
                                                           module_name, names[i])),
                          stats_xml[i].attrib['uri'])
         spec = isc.config.find_spec_part(stats_spec, names[i])
         self.assertEqual(spec['item_name'], stats_xml[i].attrib['name'])
         self.assertEqual(spec['item_type'], stats_xml[i].attrib['type'])
         self.assertEqual(spec['item_description'], stats_xml[i].attrib['description'])
         self.assertEqual(spec['item_title'], stats_xml[i].attrib['title'])
         self.assertEqual(str(spec['item_optional']).lower(), stats_xml[i].attrib['optional'])
         default = spec['item_default']
         if type(default) is int:
             default = str(default)
         if type(default) is dict or type(default) is list:
             self.assertFalse('default' in stats_xml[i].attrib)
         else:
             self.assertEqual(default, stats_xml[i].attrib['default'])
         self.assertFalse('item_format' in spec)
         self.assertFalse('format' in stats_xml[i].attrib)
Example #4
0
    def test_do_GET(self):
        self.assertTrue(type(self.stats_httpd.httpd) is list)
        self.assertEqual(len(self.stats_httpd.httpd), 1)
        self.assertEqual((self.address, self.port), self.stats_httpd.http_addrs[0])

        def check_XML_URL_PATH(path=''):
            url_path = '%s/%s' % (stats_httpd.XML_URL_PATH, path)
            url_path = urllib.parse.quote(url_path)
            self.client.putrequest('GET', url_path)
            self.client.endheaders()
            response = self.client.getresponse()
            self.assertEqual(response.getheader("Content-type"), "text/xml")
            self.assertGreater(int(response.getheader("Content-Length")), 0)
            self.assertEqual(response.status, 200)
            xml_doctype = response.readline().decode()
            xsl_doctype = response.readline().decode()
            self.assertGreater(len(xml_doctype), 0)
            self.assertGreater(len(xsl_doctype), 0)
            root = xml.etree.ElementTree.parse(response).getroot()
            self.assertGreater(root.tag.find('statistics'), 0)
            schema_loc = '{%s}schemaLocation' % XMLNS_XSI
            # check the path of XSD
            self.assertEqual(root.attrib[schema_loc],
                             stats_httpd.XSD_NAMESPACE + ' '
                             + stats_httpd.XSD_URL_PATH)
            # check the path of XSL
            self.assertTrue(xsl_doctype.startswith(
                    '<?xml-stylesheet type="text/xsl" href="' +
                    stats_httpd.XSL_URL_PATH
                    + '"?>'))
            # check whether the list of 'identifier' attributes in
            # root is same as the list of item names in DUMMY_DATA
            id_list = [ elm.attrib['identifier'] for elm in root ]
            item_list = [ it for it in \
                              stats_httpd.item_name_list(DUMMY_DATA, path) \
                              if len(it.split('/')) > 1 ]
            self.assertEqual(id_list, item_list)
            for elem in root:
                attr = elem.attrib
                value = isc.cc.data.find(DUMMY_DATA, attr['identifier'])
                # No 'value' attribute should be found in the 'item'
                # element when datatype of the value is list or dict.
                if type(value) is list or type(value) is dict:
                    self.assertFalse('value' in attr)
                # The value of the 'value' attribute should be checked
                # after casting it to string type if datatype of the
                # value is int or float. Because attr['value'] returns
                # string type even if its value is int or float.
                elif type(value) is int or type(value) is float:
                    self.assertEqual(attr['value'], str(value))
                else:
                    self.assertEqual(attr['value'], value)

        # URL is '/bind10/statistics/xml'
        check_XML_URL_PATH()
        for path in stats_httpd.item_name_list(DUMMY_DATA, ''):
            check_XML_URL_PATH(path)

        def check_XSD_URL_PATH():
            url_path = stats_httpd.XSD_URL_PATH
            url_path = urllib.parse.quote(url_path)
            self.client.putrequest('GET', url_path)
            self.client.endheaders()
            response = self.client.getresponse()
            self.assertEqual(response.getheader("Content-type"), "text/xml")
            self.assertGreater(int(response.getheader("Content-Length")), 0)
            self.assertEqual(response.status, 200)
            root = xml.etree.ElementTree.parse(response).getroot()
            url_xmlschema = '{%s}' % XMLNS_XSD
            self.assertGreater(root.tag.find('schema'), 0)
            self.assertTrue(hasattr(root, 'attrib'))
            self.assertTrue('targetNamespace' in root.attrib)
            self.assertEqual(root.attrib['targetNamespace'],
                             stats_httpd.XSD_NAMESPACE)

        # URL is '/bind10/statistics/xsd'
        check_XSD_URL_PATH()

        def check_XSL_URL_PATH():
            url_path = stats_httpd.XSL_URL_PATH
            url_path = urllib.parse.quote(url_path)
            self.client.putrequest('GET', url_path)
            self.client.endheaders()
            response = self.client.getresponse()
            self.assertEqual(response.getheader("Content-type"), "text/xml")
            self.assertGreater(int(response.getheader("Content-Length")), 0)
            self.assertEqual(response.status, 200)
            root = xml.etree.ElementTree.parse(response).getroot()
            url_trans = '{%s}' % XMLNS_XSL
            url_xhtml = '{%s}' % XMLNS_XHTML
            self.assertEqual(root.tag, url_trans + 'stylesheet')

        # URL is '/bind10/statistics/xsl'
        check_XSL_URL_PATH()

        # 302 redirect
        self.client._http_vsn_str = 'HTTP/1.1'
        self.client.putrequest('GET', '/')
        self.client.putheader('Host', self.address)
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 302)
        self.assertEqual(response.getheader('Location'),
                         "http://%s:%d%s/" % (self.address, self.port, stats_httpd.XML_URL_PATH))

        # 404 NotFound (random path)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', '/path/to/foo/bar')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', '/bind10/foo')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', '/bind10/statistics/foo')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XML_URL_PATH + 'Auth') # with no slash
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)

        # 200 ok
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XML_URL_PATH + '/')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 200)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XML_URL_PATH + '/#foo')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 200)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XML_URL_PATH + '/?foo=bar')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 200)

        # 404 NotFound (too long path)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XML_URL_PATH + '/Init/boot_time/a')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)

        # 404 NotFound (nonexistent module name)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XML_URL_PATH + '/Foo')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XSD_URL_PATH + '/Foo')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XSL_URL_PATH + '/Foo')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)

        # 404 NotFound (nonexistent item name)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XML_URL_PATH + '/Foo/bar')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XSD_URL_PATH + '/Foo/bar')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XSL_URL_PATH + '/Foo/bar')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)

        # 404 NotFound (existent module but nonexistent item name)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XML_URL_PATH + '/Auth/bar')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XSD_URL_PATH + '/Auth/bar')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)
        self.client._http_vsn_str = 'HTTP/1.0'
        self.client.putrequest('GET', stats_httpd.XSL_URL_PATH + '/Auth/bar')
        self.client.endheaders()
        response = self.client.getresponse()
        self.assertEqual(response.status, 404)
Example #5
0
 def test_item_name_list(self):
     # for a one-element list
     self.assertEqual(['a'],
                      stats_httpd.item_name_list({'a':1}, 'a'))
     # for a dict under a dict
     self.assertEqual(['a','a/b'],
                      stats_httpd.item_name_list({'a':{'b':1}}, 'a'))
     self.assertEqual(['a/b'],
                      stats_httpd.item_name_list({'a':{'b':1}}, 'a/b'))
     self.assertEqual(['a','a/b','a/b/c'],
                      stats_httpd.item_name_list({'a':{'b':{'c':1}}}, 'a'))
     self.assertEqual(['a/b','a/b/c'],
                      stats_httpd.item_name_list({'a':{'b':{'c':1}}},
                                                 'a/b'))
     self.assertEqual(['a/b/c'],
                      stats_httpd.item_name_list({'a':{'b':{'c':1}}},
                                                 'a/b/c'))
     # for a list under a dict
     self.assertEqual(['a[2]'],
                      stats_httpd.item_name_list({'a':[1,2,3]}, 'a[2]'))
     self.assertEqual(['a', 'a[0]', 'a[1]', 'a[2]'],
                      stats_httpd.item_name_list({'a':[1,2,3]}, 'a'))
     self.assertEqual(['a', 'a[0]', 'a[1]', 'a[2]'],
                      stats_httpd.item_name_list({'a':[1,2,3]}, ''))
     # for a list under a dict under a dict
     self.assertEqual(['a', 'a/b', 'a/b[0]', 'a/b[1]', 'a/b[2]'],
                      stats_httpd.item_name_list({'a':{'b':[1,2,3]}}, 'a'))
     self.assertEqual(['a', 'a/b', 'a/b[0]', 'a/b[1]', 'a/b[2]'],
                      stats_httpd.item_name_list({'a':{'b':[1,2,3]}}, ''))
     self.assertEqual(['a/b', 'a/b[0]', 'a/b[1]', 'a/b[2]'],
                      stats_httpd.item_name_list({'a':{'b':[1,2,3]}}, 'a/b'))
     # for a mixed case of the above
     self.assertEqual(['a', 'a/b', 'a/b[0]', 'a/b[1]', 'a/b[2]', 'a/c'],
                      stats_httpd.item_name_list(
             {'a':{'b':[1,2,3], 'c':1}}, 'a'))
     self.assertEqual(['a/b', 'a/b[0]', 'a/b[1]', 'a/b[2]'],
                      stats_httpd.item_name_list(
             {'a':{'b':[1,2,3], 'c':1}}, 'a/b'))
     self.assertEqual(['a/c'],
                      stats_httpd.item_name_list(
             {'a':{'b':[1,2,3], 'c':1}}, 'a/c'))
     # for specifying a wrong identifier which is not found in
     # element
     self.assertRaises(isc.cc.data.DataNotFoundError,
                      stats_httpd.item_name_list, {'x':1}, 'a')
     # for specifying a string in element and an empty string in
     # identifier
     self.assertEqual([],
                      stats_httpd.item_name_list('a', ''))
     # for specifying empty strings in element and identifier
     self.assertEqual([],
                      stats_httpd.item_name_list('', ''))
     # for specifying wrong element, which is an non-empty string,
     # and an non-empty string in identifier
     self.assertRaises(isc.cc.data.DataTypeError,
                      stats_httpd.item_name_list, 'a', 'a')
     # for specifying None in element and identifier
     self.assertRaises(isc.cc.data.DataTypeError,
                      stats_httpd.item_name_list, None, None)
     # for specifying non-dict in element
     self.assertRaises(isc.cc.data.DataTypeError,
                      stats_httpd.item_name_list, [1,2,3], 'a')
     self.assertRaises(isc.cc.data.DataTypeError,
                      stats_httpd.item_name_list, [1,2,3], '')
     # for checking key names sorted which consist of element
     num = 11
     keys = [ 'a', 'aa', 'b' ]
     keys.sort(reverse=True)
     dictlist = dict([ (k, list(range(num))) for k in keys ])
     keys.sort()
     ans = []
     for k in keys:
         ans += [k] + [ '%s[%d]' % (k, i) for i in range(num) ]
     self.assertEqual(ans,
                      stats_httpd.item_name_list(dictlist, ''))