Browse Source

[2298_1] Merge branch 'trac2298_1'

Naoki Kambe 12 years ago
parent
commit
14af6f372b
2 changed files with 129 additions and 2 deletions
  1. 50 1
      src/bin/stats/stats_httpd.py.in
  2. 79 1
      src/bin/stats/tests/b10-stats-httpd_test.py

+ 50 - 1
src/bin/stats/stats_httpd.py.in

@@ -1,6 +1,6 @@
 #!@PYTHON@
 
-# Copyright (C) 2011  Internet Systems Consortium.
+# Copyright (C) 2011-2012  Internet Systems Consortium.
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -72,6 +72,55 @@ XSD_NAMESPACE = 'http://bind10.isc.org/bind10'
 # Assign this process name
 isc.util.process.rename()
 
+def item_name_list(element, identifier):
+    """Return a list of strings. The strings are string expression of
+    the first argument element which is dict type. The second argument
+    identifier is a string for specifying the strings which are
+    returned from this method as a list. For example, if we specify as
+
+      item_name_list({'a': {'aa': [0, 1]}, 'b': [0, 1]}, 'a/aa'),
+
+    then it returns
+
+      ['a/aa', 'a/aa[0]', 'a/aa[1]'].
+
+    If an empty string is specified in the second argument, all
+    possible strings are returned as a list.  In that example if we
+    specify an empty string in the second argument, then it returns
+
+      ['a', 'a/aa', 'a/aa[0]', 'a/aa[1]', 'b', 'b[0]', 'b[1]'].
+
+    The key name of element which is in the first argument is sorted.
+    Even if we specify as
+
+      item_name_list({'xx': 0, 'a': 1, 'x': 2}, ''),
+
+    then it returns
+
+      ['a', 'x', 'xx'].
+
+    This method internally invokes isc.cc.data.find(). The arguments
+    of this method are passed to isc.cc.data.find(). So an exception
+    DataNotFoundError or DataTypeError might be raised via
+    isc.cc.data.find() depending on the arguments. See details of
+    isc.cc.data.find() for more information about exceptions"""
+    elem = isc.cc.data.find(element, identifier)
+    ret = []
+    ident = identifier
+    if ident:
+        ret.append(ident)
+    if type(elem) is dict:
+        if ident:
+            ident = ident + '/'
+        for key in sorted(elem.keys()):
+            idstr = '%s%s' % (ident, key)
+            ret += item_name_list(element, idstr)
+    elif type(elem) is list:
+        for i in range(0, len(elem)):
+            idstr = '%s[%d]' % (ident, i)
+            ret += item_name_list(element, idstr)
+    return ret
+
 class HttpHandler(http.server.BaseHTTPRequestHandler):
     """HTTP handler class for HttpServer class. The class inhrits the super
     class http.server.BaseHTTPRequestHandler. It implemets do_GET()

+ 79 - 1
src/bin/stats/tests/b10-stats-httpd_test.py

@@ -1,4 +1,4 @@
-# Copyright (C) 2011  Internet Systems Consortium.
+# Copyright (C) 2011-2012  Internet Systems Consortium.
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -113,6 +113,84 @@ def is_ipv6_enabled(address='::1', port=8001):
             if sock: sock.close()
     return False
 
+class TestItemNameList(unittest.TestCase):
+
+    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 adict 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, ''))
+
 class TestHttpHandler(unittest.TestCase):
     """Tests for HttpHandler class"""
     def setUp(self):