BIND 10 trac917, updated. 50e96053742a30584f91a6bdb4b788977cd166bf [917] remove the obvious returns of None

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Nov 8 08:27:22 UTC 2011


The branch, trac917 has been updated
       via  50e96053742a30584f91a6bdb4b788977cd166bf (commit)
       via  f1e08d75cabc45454a9bde86158dc8c7348d7f9d (commit)
       via  cc48074a9fec60ef9ba69991549f9e167e620225 (commit)
       via  8e8607c6faa34d9493a831054ecb64281f1f06c7 (commit)
       via  4ab7d17edc10ce4f7b834709aa009aba4db9d877 (commit)
       via  df02b63fe1176c572a7eee996921f211ca970953 (commit)
       via  f8a64959bc5f3ddf68ba4d01bee092bf4f1f9558 (commit)
       via  7e96227163334ecd54e506bd2cedb58d3f6cf91d (commit)
      from  6d5f34008d7e793546fd990cad11e40268c0ff04 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 50e96053742a30584f91a6bdb4b788977cd166bf
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Tue Nov 8 07:49:26 2011 +0000

    [917] remove the obvious returns of None

commit f1e08d75cabc45454a9bde86158dc8c7348d7f9d
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Tue Nov 8 07:26:50 2011 +0000

    [917] use assertEqual instead of assertTrue

commit cc48074a9fec60ef9ba69991549f9e167e620225
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Tue Nov 8 07:24:30 2011 +0000

    [917] add more testcases of 404 NotFound (existent module but
    nonexistent item name)

commit 8e8607c6faa34d9493a831054ecb64281f1f06c7
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Tue Nov 8 07:19:51 2011 +0000

    [917] add more docstrings to the functions xml_handler, xsd_handler and xsl_handler

commit 4ab7d17edc10ce4f7b834709aa009aba4db9d877
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Tue Nov 8 07:10:58 2011 +0000

    [917] add more docstrings to the functions get_stats_data and get_stats_spec

commit df02b63fe1176c572a7eee996921f211ca970953
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Tue Nov 8 06:50:03 2011 +0000

    [917] stats-httpd returns the 404 status code if the specified module
    name or item name is incorrect
    
    create a new exception StatsHttpdDataError which is an exception due
    to the data specified to the stats daemon

commit f8a64959bc5f3ddf68ba4d01bee092bf4f1f9558
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Tue Nov 8 06:16:34 2011 +0000

    [917] remove the last slashes because of the failure of unittests

commit 7e96227163334ecd54e506bd2cedb58d3f6cf91d
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Tue Nov 8 05:58:28 2011 +0000

    [917] add missing checking the XSD and XSL paths in the XML document

-----------------------------------------------------------------------

Summary of changes:
 src/bin/stats/stats_httpd.py.in             |   80 ++++++++++++++++++-----
 src/bin/stats/tests/b10-stats-httpd_test.py |   92 +++++++++++++++++++++------
 src/bin/stats/tests/b10-stats_test.py       |    4 +-
 3 files changed, 136 insertions(+), 40 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/bin/stats/stats_httpd.py.in b/src/bin/stats/stats_httpd.py.in
index 6dab53f..0e4e91c 100644
--- a/src/bin/stats/stats_httpd.py.in
+++ b/src/bin/stats/stats_httpd.py.in
@@ -125,13 +125,14 @@ class HttpHandler(http.server.BaseHTTPRequestHandler):
                     # Couldn't find HOST
                     self.send_error(404)
                     return None
-        except StatsHttpdError as err:
+        except StatsHttpdDataError as err:
             # Couldn't find neither specified module name nor
             # specified item name
-            if str(err).startswith('Stats module: specified arguments are incorrect:'):
-                self.send_error(404)
-            else:
-                self.send_error(500)
+            self.send_error(404)
+            logger.error(STATHTTPD_SERVER_ERROR, err)
+            return None
+        except StatsHttpdError as err:
+            self.send_error(500)
             logger.error(STATHTTPD_SERVER_ERROR, err)
             return None
         else:
@@ -171,6 +172,12 @@ class StatsHttpdError(Exception):
     main routine."""
     pass
 
+class StatsHttpdDataError(Exception):
+    """Exception class for StatsHttpd class. The reason seems to be
+    due to the data. It is intended to be thrown from the the
+    StatsHttpd object to the HttpHandler object or main routine."""
+    pass
+
 class StatsHttpd:
     """The main class of HTTP server of HTTP/XML interface for
     statistics module. It handles HTTP requests, and command channel
@@ -362,7 +369,15 @@ class StatsHttpd:
 
     def get_stats_data(self, owner=None, name=None):
         """Requests statistics data to the Stats daemon and returns
-        the data which obtains from it. args are owner and name."""
+        the data which obtains from it. The first argument is the
+        module name which owns the statistics data, the second
+        argument is one name of the statistics items which the the
+        module owns. The second argument cannot be specified when the
+        first argument is not specified. It returns the statistics
+        data of the specified module or item. When the session timeout
+        or the session error is occurred, it raises
+        StatsHttpdError. When the stats daemon returns none-zero
+        value, it raises StatsHttpdDataError."""
         param = {}
         if owner is None and name is None:
             param = None
@@ -384,11 +399,19 @@ class StatsHttpd:
             if rcode == 0:
                 return value
             else:
-                raise StatsHttpdError("Stats module: %s" % str(value))
+                raise StatsHttpdDataError("Stats module: %s" % str(value))
 
     def get_stats_spec(self, owner=None, name=None):
         """Requests statistics data to the Stats daemon and returns
-        the data which obtains from it. args are owner and name."""
+        the data which obtains from it. The first argument is the
+        module name which owns the statistics data, the second
+        argument is one name of the statistics items which the the
+        module owns. The second argument cannot be specified when the
+        first argument is not specified. It returns the statistics
+        specification of the specified module or item. When the
+        session timeout or the session error is occurred, it raises
+        StatsHttpdError. When the stats daemon returns none-zero
+        value, it raises StatsHttpdDataError."""
         param = {}
         if owner is None and name is None:
             param = None
@@ -405,7 +428,7 @@ class StatsHttpd:
                 if rcode == 0:
                     return value
                 else:
-                    raise StatsHttpdError("Stats module: %s" % str(value))
+                    raise StatsHttpdDataError("Stats module: %s" % str(value))
         except (isc.cc.session.SessionTimeout,
                 isc.cc.session.SessionError) as err:
             raise StatsHttpdError("%s: %s" %
@@ -413,8 +436,14 @@ class StatsHttpd:
 
 
     def xml_handler(self, module_name=None, item_name=None):
-        """Handler which requests to Stats daemon to obtain statistics
-        data and returns the body of XML document"""
+        """Requests the specified statistics data and specification by
+        using the functions get_stats_data and get_stats_spec
+        respectively and loads the XML template file and returns the
+        string of the XML document.The first argument is the module
+        name which owns the statistics data, the second argument is
+        one name of the statistics items which the the module
+        owns. The second argument cannot be specified when the first
+        argument is not specified."""
 
         def stats_data2xml(stats_spec, stats_data, xml_elem):
             """Internal use for xml_handler. Reads stats_data and
@@ -453,13 +482,18 @@ class StatsHttpd:
                     stats_data2xml(item_spec,
                                    stats_data[item_spec['item_name']],
                                    xml_elem)
-            return None
 
         stats_spec = self.get_stats_spec(module_name, item_name)
         stats_data = self.get_stats_data(module_name, item_name)
+        # make the path xxx/module/item if specified respectively
+        path_info = ''
+        if module_name is not None and item_name is not None:
+            path_info = '/' + module_name + '/' + item_name
+        elif module_name is not None:
+            path_info = '/' + module_name
         xml_elem = xml.etree.ElementTree.Element(
             'bind10:statistics',
-            attrib={ 'xsi:schemaLocation' : XSD_NAMESPACE + ' ' + XSD_URL_PATH,
+            attrib={ 'xsi:schemaLocation' : XSD_NAMESPACE + ' ' + XSD_URL_PATH + path_info,
                      'xmlns:bind10' : XSD_NAMESPACE,
                      'xmlns:xsi' : "http://www.w3.org/2001/XMLSchema-instance" })
         stats_data2xml(stats_spec, stats_data, xml_elem)
@@ -473,12 +507,18 @@ class StatsHttpd:
                          encoding='us-ascii')
         self.xml_body = self.open_template(XML_TEMPLATE_LOCATION).substitute(
             xml_string=xml_string,
-            xsl_url_path=XSL_URL_PATH)
+            xsl_url_path=XSL_URL_PATH + path_info)
         assert self.xml_body is not None
         return self.xml_body
 
     def xsd_handler(self, module_name=None, item_name=None):
-        """Handler which just returns the body of XSD document"""
+        """Requests the specified statistics specification by using
+        the function get_stats_spec respectively and loads the XSD
+        template file and returns the string of the XSD document.The
+        first argument is the module name which owns the statistics
+        data, the second argument is one name of the statistics items
+        which the the module owns. The second argument cannot be
+        specified when the first argument is not specified."""
 
         def stats_spec2xsd(stats_spec, xsd_elem):
             """Internal use for xsd_handler. Reads stats_spec
@@ -555,7 +595,6 @@ class StatsHttpd:
             elif type(stats_spec) is list:
                 for item_spec in stats_spec:
                     stats_spec2xsd(item_spec, xsd_elem)
-            return None
 
         # for XSD
         stats_spec = self.get_stats_spec(module_name, item_name)
@@ -596,7 +635,13 @@ class StatsHttpd:
         return self.xsd_body
 
     def xsl_handler(self, module_name=None, item_name=None):
-        """Handler which just returns the body of XSL document"""
+        """Requests the specified statistics specification by using
+        the function get_stats_spec respectively and loads the XSL
+        template file and returns the string of the XSL document.The
+        first argument is the module name which owns the statistics
+        data, the second argument is one name of the statistics items
+        which the the module owns. The second argument cannot be
+        specified when the first argument is not specified."""
 
         def stats_spec2xsl(stats_spec, xsl_elem, path=XML_URL_PATH):
             """Internal use for xsl_handler. Reads stats_spec
@@ -714,7 +759,6 @@ class StatsHttpd:
                     else:
                         table.append(tr)
                 xsl_elem.append(table)
-            return None
 
         # for XSL
         stats_spec = self.get_stats_spec(module_name, item_name)
diff --git a/src/bin/stats/tests/b10-stats-httpd_test.py b/src/bin/stats/tests/b10-stats-httpd_test.py
index 95ce93d..2b2b1b4 100644
--- a/src/bin/stats/tests/b10-stats-httpd_test.py
+++ b/src/bin/stats/tests/b10-stats-httpd_test.py
@@ -146,12 +146,23 @@ class TestHttpHandler(unittest.TestCase):
             self.assertEqual(response.getheader("Content-type"), "text/xml")
             self.assertTrue(int(response.getheader("Content-Length")) > 0)
             self.assertEqual(response.status, 200)
+            xml_doctype = response.readline().decode()
+            xsl_doctype = response.readline().decode()
+            self.assertTrue(len(xml_doctype) > 0)
+            self.assertTrue(len(xsl_doctype) > 0)
             root = xml.etree.ElementTree.parse(response).getroot()
             self.assertTrue(root.tag.find('statistics') > 0)
-            for (k,v) in root.attrib.items():
-                if k.find('schemaLocation') > 0:
-                    self.assertEqual(v, stats_httpd.XSD_NAMESPACE + ' ' + stats_httpd.XSD_URL_PATH)
+            schema_loc = '{http://www.w3.org/2001/XMLSchema-instance}schemaLocation'
             if item is None and mod is None:
+                # 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
+                        + '"?>'))
                 for m in DUMMY_DATA:
                     for k in DUMMY_DATA[m].keys():
                         self.assertIsNotNone(root.find(m + '/' + k))
@@ -161,6 +172,15 @@ class TestHttpHandler(unittest.TestCase):
                                 for i in v:
                                     self.assertIsNotNone(itm.find('zones/' + i))
             elif item is None:
+                # check the path of XSD
+                self.assertEqual(root.attrib[schema_loc],
+                                 stats_httpd.XSD_NAMESPACE + ' '
+                                 + stats_httpd.XSD_URL_PATH + '/' + mod)
+                # check the path of XSL
+                self.assertTrue(xsl_doctype.startswith( 
+                                 '<?xml-stylesheet type="text/xsl" href="'
+                                 + stats_httpd.XSL_URL_PATH + '/' + mod
+                                 + '"?>'))
                 for k in DUMMY_DATA[mod].keys():
                     self.assertIsNotNone(root.find(k))
                     itm = root.find(k)
@@ -169,6 +189,15 @@ class TestHttpHandler(unittest.TestCase):
                             for i in v:
                                 self.assertIsNotNone(itm.find('zones/' + i))
             else:
+                # check the path of XSD
+                self.assertEqual(root.attrib[schema_loc],
+                                 stats_httpd.XSD_NAMESPACE + ' '
+                                 + stats_httpd.XSD_URL_PATH + '/' + mod + '/' + item)
+                # check the path of XSL
+                self.assertTrue(xsl_doctype.startswith( 
+                                 '<?xml-stylesheet type="text/xsl" href="'
+                                 + stats_httpd.XSL_URL_PATH + '/' + mod + '/' + item
+                                 + '"?>'))
                 self.assertIsNotNone(root.find(item))
 
         # URL is '/bind10/statistics/xml'
@@ -278,70 +307,70 @@ class TestHttpHandler(unittest.TestCase):
                     for (k, v) in itms.items():
                         if type(v) is list:
                             xslpath = url_xhtml + 'tr/' + url_xhtml + 'td/' \
-                                + url_xhtml + 'table/' + url_trans + 'for-each/'
+                                + url_xhtml + 'table/' + url_trans + 'for-each'
                             itm_fe = dict([ (x.attrib['select'], x) for x in mod_fe[mod].findall(xslpath) ])
                             self.assertTrue(k in itm_fe)
                             for itms in v:
                                 xslpath = url_xhtml + 'tr/' + url_xhtml + 'td/' \
-                                    + url_xhtml + 'table/' + url_trans + 'for-each/'
+                                    + url_xhtml + 'table/' + url_trans + 'for-each'
                                 itm_fe = dict([ (x.attrib['select'], x) for x in itm_fe[k].findall(xslpath) ])
                                 self.assertTrue('zones' in itm_fe)
                                 for (k, v) in itms.items():
                                     xslpath = url_xhtml + 'tr/' + url_xhtml + 'td/' \
                                         + url_xhtml + 'table/' + url_xhtml + 'tr/' \
-                                        + url_xhtml + 'td/' + url_trans + 'value-of/'
+                                        + url_xhtml + 'td/' + url_trans + 'value-of'
                                     itm_vo = [ x.attrib['select'] for x in itm_fe['zones'].findall(xslpath) ]
                                     self.assertTrue(k in itm_vo)
                         else:
                             xslpath = url_xhtml + 'tr/' + url_xhtml + 'td/' \
                                 + url_xhtml + 'table/' + url_xhtml + 'tr/' \
-                                + url_xhtml + 'td/' + url_trans + 'value-of/'
+                                + url_xhtml + 'td/' + url_trans + 'value-of'
                             itm_vo = [ x.attrib['select'] for x in mod_fe[mod].findall(xslpath) ]
                             self.assertTrue(k in itm_vo)
             elif item is None:
                 for (k, v) in DUMMY_DATA[mod].items():
                     if type(v) is list:
                         xslpath = url_trans + 'template/' + url_xhtml + 'table/' \
-                            + url_trans + 'for-each/'
+                            + url_trans + 'for-each'
                         itm_fe = dict([ (x.attrib['select'], x) for x in root.findall(xslpath) ])
                         self.assertTrue(k in itm_fe)
                         for itms in v:
                             xslpath = url_xhtml + 'tr/' + url_xhtml + 'td/' \
-                                + url_xhtml + 'table/' + url_trans + 'for-each/'
+                                + url_xhtml + 'table/' + url_trans + 'for-each'
                             itm_fe = dict([ (x.attrib['select'], x) for x in itm_fe[k].findall(xslpath) ])
                             self.assertTrue('zones' in itm_fe)
                             for (k, v) in itms.items():
                                 xslpath = url_xhtml + 'tr/' + url_xhtml + 'td/' \
                                     + url_xhtml + 'table/' + url_xhtml + 'tr/' \
-                                    + url_xhtml + 'td/' + url_trans + 'value-of/'
+                                    + url_xhtml + 'td/' + url_trans + 'value-of'
                                 itm_vo = [ x.attrib['select'] for x in itm_fe['zones'].findall(xslpath) ]
                                 self.assertTrue(k in itm_vo)
                     else:
                         xslpath = url_trans + 'template/' + url_xhtml + 'table/' \
-                            + url_xhtml + 'tr/' + url_xhtml + 'td/' + url_trans + 'value-of/'
+                            + url_xhtml + 'tr/' + url_xhtml + 'td/' + url_trans + 'value-of'
                         itm_vo = dict([ (x.attrib['select'], x) for x in root.findall(xslpath) ])
                         self.assertTrue(k in itm_vo)
             else:
                 (k, v) = (item, DUMMY_DATA[mod][item])
                 if type(v) is list:
                     xslpath = url_trans + 'template/' + url_xhtml + 'table/' \
-                        + url_trans + 'for-each/'
+                        + url_trans + 'for-each'
                     itm_fe = dict([ (x.attrib['select'], x) for x in root.findall(xslpath) ])
                     self.assertTrue(k in itm_fe)
                     for itms in v:
                         xslpath = url_xhtml + 'tr/' + url_xhtml + 'td/' \
-                            + url_xhtml + 'table/' + url_trans + 'for-each/'
+                            + url_xhtml + 'table/' + url_trans + 'for-each'
                         itm_fe = dict([ (x.attrib['select'], x) for x in itm_fe[k].findall(xslpath) ])
                         self.assertTrue('zones' in itm_fe)
                         for (k, v) in itms.items():
                             xslpath = url_xhtml + 'tr/' + url_xhtml + 'td/' \
                                 + url_xhtml + 'table/' + url_xhtml + 'tr/' \
-                                + url_xhtml + 'td/' + url_trans + 'value-of/'
+                                + url_xhtml + 'td/' + url_trans + 'value-of'
                             itm_vo = [ x.attrib['select'] for x in itm_fe['zones'].findall(xslpath) ]
                             self.assertTrue(k in itm_vo)
                 else:
                     xslpath = url_trans + 'template/' + url_xhtml + 'table/' \
-                        + url_xhtml + 'tr/' + url_xhtml + 'td/' + url_trans + 'value-of/'
+                        + url_xhtml + 'tr/' + url_xhtml + 'td/' + url_trans + 'value-of'
                     itm_vo = dict([ (x.attrib['select'], x) for x in root.findall(xslpath) ])
                     self.assertTrue(k in itm_vo)
 
@@ -422,6 +451,23 @@ class TestHttpHandler(unittest.TestCase):
         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', '/bind10/statistics/xml/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', '/bind10/statistics/xsd/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', '/bind10/statistics/xsl/Auth/bar')
+        self.client.endheaders()
+        response = self.client.getresponse()
+        self.assertEqual(response.status, 404)
+
     def test_do_GET_failed1(self):
         # checks status
         self.assertEqual(send_command("status", "Stats"),
@@ -454,26 +500,26 @@ class TestHttpHandler(unittest.TestCase):
         # failure case(Stats replies an error)
         self.stats.mccs.set_command_handler(
             lambda cmd, args: \
-                isc.config.ccsession.create_answer(1, "I have an error.")
+                isc.config.ccsession.create_answer(1, "specified arguments are incorrect: I have an error.")
             )
 
         # request XML
         self.client.putrequest('GET', stats_httpd.XML_URL_PATH)
         self.client.endheaders()
         response = self.client.getresponse()
-        self.assertEqual(response.status, 500)
+        self.assertEqual(response.status, 404)
 
         # request XSD
         self.client.putrequest('GET', stats_httpd.XSD_URL_PATH)
         self.client.endheaders()
         response = self.client.getresponse()
-        self.assertEqual(response.status, 500)
+        self.assertEqual(response.status, 404)
 
         # request XSL
         self.client.putrequest('GET', stats_httpd.XSL_URL_PATH)
         self.client.endheaders()
         response = self.client.getresponse()
-        self.assertEqual(response.status, 500)
+        self.assertEqual(response.status, 404)
 
     def test_do_HEAD(self):
         self.client.putrequest('HEAD', stats_httpd.XML_URL_PATH)
@@ -518,12 +564,18 @@ class TestHttpServer(unittest.TestCase):
 class TestStatsHttpdError(unittest.TestCase):
     """Tests for StatsHttpdError exception"""
 
-    def test_raises(self):
+    def test_raises1(self):
         try:
             raise stats_httpd.StatsHttpdError('Nothing')
         except stats_httpd.StatsHttpdError as err:
             self.assertEqual(str(err), 'Nothing')
 
+    def test_raises2(self):
+        try:
+            raise stats_httpd.StatsHttpdDataError('Nothing')
+        except stats_httpd.StatsHttpdDataError as err:
+            self.assertEqual(str(err), 'Nothing')
+
 class TestStatsHttpd(unittest.TestCase):
     """Tests for StatsHttpd class"""
 
diff --git a/src/bin/stats/tests/b10-stats_test.py b/src/bin/stats/tests/b10-stats_test.py
index cb4420b..b9b491d 100644
--- a/src/bin/stats/tests/b10-stats_test.py
+++ b/src/bin/stats/tests/b10-stats_test.py
@@ -460,9 +460,9 @@ class TestStats(unittest.TestCase):
         self.assertEqual(len(schema), 3)
         for item in schema:
             if item['item_type'] == 'list':
-                self.assertTrue(len(item) == 7)
+                self.assertEqual(len(item), 7)
             else:
-                self.assertTrue(len(item) == 6)
+                self.assertEqual(len(item), 6)
             self.assertTrue('item_name' in item)
             self.assertTrue('item_type' in item)
             self.assertTrue('item_optional' in item)




More information about the bind10-changes mailing list