API: Cleanup APIs interface.api
[vpp.git] / test / vpp_object.py
1 """ abstract vpp object and object registry """
2
3 import abc
4 import six
5
6 from six import moves
7
8
9 @six.add_metaclass(abc.ABCMeta)
10 class VppObject(object):
11     """ Abstract vpp object """
12
13     @abc.abstractmethod
14     def add_vpp_config(self):
15         """ Add the configuration for this object to vpp. """
16         pass
17
18     @abc.abstractmethod
19     def query_vpp_config(self):
20         """Query the vpp configuration.
21
22         :return: True if the object is configured"""
23         pass
24
25     @abc.abstractmethod
26     def remove_vpp_config(self):
27         """ Remove the configuration for this object from vpp. """
28         pass
29
30     @abc.abstractmethod
31     def object_id(self):
32         """ Return a unique string representing this object. """
33         pass
34
35
36 class VppObjectRegistry(object):
37     """ Class which handles automatic configuration cleanup. """
38     _shared_state = {}
39
40     def __init__(self):
41         self.__dict__ = self._shared_state
42         if not hasattr(self, "_object_registry"):
43             self._object_registry = []
44         if not hasattr(self, "_object_dict"):
45             self._object_dict = dict()
46
47     def register(self, obj, logger):
48         """ Register an object in the registry. """
49         if obj.object_id() not in self._object_dict:
50             self._object_registry.append(obj)
51             self._object_dict[obj.object_id()] = obj
52             logger.debug("REG: registering %s" % obj)
53         else:
54             logger.debug("REG: duplicate add, ignoring (%s)" % obj)
55
56     def unregister_all(self, logger):
57         """ Remove all object registrations from registry. """
58         logger.debug("REG: removing all object registrations")
59         self._object_registry = []
60         self._object_dict = dict()
61
62     def remove_vpp_config(self, logger):
63         """
64         Remove configuration (if present) from vpp and then remove all objects
65         from the registry.
66         """
67         if not self._object_registry:
68             logger.info("REG: No objects registered for auto-cleanup.")
69             return
70         logger.info("REG: Removing VPP configuration for registered objects")
71         # remove the config in reverse order as there might be dependencies
72         failed = []
73         for obj in reversed(self._object_registry):
74             if obj.query_vpp_config():
75                 logger.info("REG: Removing configuration for %s" % obj)
76                 obj.remove_vpp_config()
77                 if obj.query_vpp_config():
78                     failed.append(obj)
79             else:
80                 logger.info(
81                     "REG: Skipping removal for %s, configuration not present" %
82                     obj)
83         self.unregister_all(logger)
84         if failed:
85             logger.error("REG: Couldn't remove configuration for object(s):")
86             for obj in failed:
87                 logger.error(moves.reprlib.repr(obj))
88             raise Exception("Couldn't remove configuration for object(s): %s" %
89                             (", ".join(str(x) for x in failed)))