Whamcloud - gitweb
LU-17705 ptlrpc: replace synchronize_rcu() with rcu_barrier()
[fs/lustre-release.git] / contrib / debug_tools / epython_scripts / crashlib / input / enumtools.py
1
2 """
3 Routines for handling enums (or other symbolic names)
4 Copyright 2015 Cray Inc.  All Rights Reserved
5 """
6
7 import uflookup
8
9 class NameSet:
10     """Two-way translation between int values (enums, #defines) and strings.
11     Also provides access to value by e.g.:
12     vms = NameSet()  # vmstat nameset
13     vms.AddName("NR_FILE_MAPPED", 8)
14     vms.NR_FILE_MAPPED == 8
15
16     The advantages over just using a dict include:
17
18     * Define the values once, and get value->string, string->value,
19       and python identifier ns.<name> as above.
20     * The auto-incrementing _next_value
21       """
22
23     def __init__(self, mapping=None):
24         """Create and initialize a NameSet object
25
26         Arguments:
27             mapping:    if specified, provides a mapping object, e.g. dict,
28                         that supplies the initial key(name)/value pairs.
29         """
30         self.value_to_name = {}
31         self.name_to_value = {}
32
33         self._next_value = 0
34 #        self._sorted_values = []
35 #        self._sorted_names = []
36
37         if mapping is not None:
38             self.addMap(mapping)
39
40     def addName(self, name, value=None):
41         """Add a single name, by default using the next value.
42
43         If two names end up with the same value, the value will map
44         only to the first of them.
45         """
46
47         if name in self.name_to_value.keys():
48             raise ValueError("Name {0} already defined (value {1})".format(
49                 name, self.name_to_value[name]))
50         try:
51             getattr(self, name)
52         except AttributeError:
53             pass
54         else:
55             raise ValueError("Value {0} already used by NameSet object!".
56                              format(value))
57
58         if value is None:
59             value = self._next_value
60         self._next_value = value + 1
61
62         self.name_to_value[name] = value
63         if value not in self.value_to_name:
64             self.value_to_name[value] = name
65  #       self._sorted_values = []
66  #       self._sorted_names = []
67
68         setattr(self, name, value)
69
70     def addNames(self, *namelist):
71         """Add a list of names, each using the respective next value"""
72         map(self.addName, namelist)
73
74     def addMap(self, mapping):
75         """Add the key/value pairs from a mapping type"""
76         for k, v in mapping.items():
77             self.addName(k, v)
78
79     def UFLookup(self, key, **kwargs):
80         return uflookup.UFLookup(self.name_to_value, key, **kwargs)
81
82 #    def somethingUsingSortedArrays:
83 #        if not self._sorted_values:
84 #            self._sorted_values = sorted(self.value_to_name.keys())
85 #            self._sorted_names = sorted(self.name_to_value.keys())
86
87
88
89 if __name__ == '__main__':
90     import unittest
91
92     class Test_NameSet(unittest.TestCase):
93         """Test the NameSet class"""
94
95         def VerifyName(self, name, value):
96             """Verify that self.ns has name <-> value"""
97             self.assertEqual(value, self.ns.name_to_value[name])
98             self.assertEqual(value, getattr(self.ns, name))
99             self.assertEqual(name, self.ns.value_to_name[value])
100
101     class Test_Empty(Test_NameSet):
102         """Test an empty NameSet"""
103         def setUp(self):
104             self.ns = NameSet()
105
106         def test_empty_vtn(self):
107             self.assertEqual(0, len(self.ns.value_to_name))
108         def test_empty_ntv(self):
109             self.assertEqual(0, len(self.ns.name_to_value))
110
111
112     class Test_addName(Test_NameSet):
113         """Test addName"""
114         def setUp(self):
115             self.ns = NameSet()
116
117         def test_add_one_name(self):
118             self.ns.addName("FOO")
119
120             self.VerifyName("FOO", 0)
121             self.assertEqual(0, self.ns.FOO)
122
123         def test_add_two_names(self):
124             self.ns.addName("BAR")
125             self.ns.addName("BAZ")
126
127             self.VerifyName("BAR", 0)
128             self.VerifyName("BAZ", 1)
129             self.assertEqual(0, self.ns.BAR)
130             self.assertEqual(1, self.ns.BAZ)
131
132
133         def test_add_namevalue(self):
134             self.ns.addName("FOO", 87)
135             self.VerifyName("FOO", 87)
136             self.assertEqual(87, self.ns.FOO)
137
138         def test_reuse_existing_value(self):
139             self.ns.addName("FOO", 2)
140             self.ns.addName("B0",0)
141             self.ns.addName("B1")
142             self.ns.addName("B2")
143             self.ns.addName("B3")
144
145             self.VerifyName("FOO", 2)
146             self.VerifyName("B0", 0)
147             self.VerifyName("B1", 1)
148             self.assertEqual(2, self.ns.name_to_value["B2"])
149             self.VerifyName("B3", 3)
150
151             self.assertEqual(2, self.ns.FOO)
152             self.assertEqual(0, self.ns.B0)
153             self.assertEqual(1, self.ns.B1)
154             self.assertEqual(3, self.ns.B3)
155
156         def test_addNames(self):
157             self.ns.addNames("FOO", "BAR", "BAZ")
158             self.VerifyName("FOO", 0)
159             self.VerifyName("BAR", 1)
160             self.VerifyName("BAZ", 2)
161
162             self.assertEqual(0, self.ns.FOO)
163             self.assertEqual(1, self.ns.BAR)
164             self.assertEqual(2, self.ns.BAZ)
165
166         def test_addDupName(self):
167             self.ns.addName("FOO", 1)
168             self.assertRaises(ValueError, self.ns.addName, "FOO", 2)
169
170         def test_addDupValue(self):
171             self.ns.addName("FOO")
172             self.ns.addName("BAR", 0)
173
174             self.VerifyName("FOO", 0)
175             self.assertEqual(0, self.ns.name_to_value["BAR"])
176
177         def test_addMoreDupValues(self):
178             self.ns.addName("FOO")
179             self.ns.addName("BAR", 0)
180             self.ns.addName("BAZ", 0)
181
182             self.VerifyName("FOO", 0)
183             self.assertEqual(0, self.ns.name_to_value["BAR"])
184             self.assertEqual(0, self.ns.name_to_value["BAZ"])
185
186
187         def test_addConflicting(self):
188             self.assertRaises(ValueError, self.ns.addName, "addName")
189
190
191     class Test_mapping(Test_NameSet):
192         """Test map handling"""
193         def setUp(self):
194             self.ns = NameSet(mapping={"SLEEPY":1, "GRUMPY": 0})
195
196         def test_constructor(self):
197             self.VerifyName("SLEEPY", 1)
198             self.VerifyName("GRUMPY", 0)
199
200         def test_addMap(self):
201             self.ns.addMap({"DOC": 9, "BASHFUL": 3})
202
203             self.VerifyName("SLEEPY", 1)
204             self.VerifyName("GRUMPY", 0)
205             self.VerifyName("DOC", 9)
206             self.VerifyName("BASHFUL", 3)
207
208
209     # Run all unit tests
210     unittest.main()
211