ns-3 CCN tests
[nepi.git] / src / nepi / execution / resource.py
index e1679a8..c56aa5b 100644 (file)
@@ -186,14 +186,13 @@ class ResourceManager(Logger):
         attributes.
 
         """
-        
         critical = Attribute("critical", 
                 "Defines whether the resource is critical. "
                 "A failure on a critical resource will interrupt "
                 "the experiment. ",
                 type = Types.Bool,
                 default = True,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(critical)
         
@@ -259,6 +258,14 @@ class ResourceManager(Logger):
         """
         return copy.deepcopy(cls._attributes.values())
 
+    @classmethod
+    def get_attribute(cls, name):
+        """ Returns a copy of the attribute with name 'name'
+
+        """
+        return copy.deepcopy(cls._attributes[name])
+
+
     @classmethod
     def get_traces(cls):
         """ Returns a copy of the traces
@@ -281,6 +288,32 @@ class ResourceManager(Logger):
         """
         return cls._backend
 
+    @classmethod
+    def get_global(cls, name):
+        """ Returns the value of a global attribute
+            Global attribute meaning an attribute for 
+            all the resources from a rtype
+
+        :param name: Name of the attribute
+        :type name: str
+        :rtype: str
+        """
+        global_attr = cls._attributes[name]
+        return global_attr.value
+
+    @classmethod
+    def set_global(cls, name, value):
+        """ Set value for a global attribute
+
+        :param name: Name of the attribute
+        :type name: str
+        :param name: Value of the attribute
+        :type name: str
+        """
+        global_attr = cls._attributes[name]
+        global_attr.value = value
+        return value
+
     def __init__(self, ec, guid):
         super(ResourceManager, self).__init__(self.get_rtype())
         
@@ -504,7 +537,6 @@ class ResourceManager(Logger):
         with self._release_lock:
             if self._state != ResourceState.RELEASED:
                 self.do_deploy()
-                self.debug("----- READY ---- ")
 
     def release(self):
         """ Perform actions to free resources used by the RM.
@@ -524,8 +556,7 @@ class ResourceManager(Logger):
                 err = traceback.format_exc()
                 self.error(err)
 
-            self.set_released()
-            self.debug("----- RELEASED ---- ")
+                self.set_released()
 
     def fail(self):
         """ Sets the RM to state FAILED.
@@ -548,6 +579,7 @@ class ResourceManager(Logger):
         """
         attr = self._attrs[name]
         attr.value = value
+        return value
 
     def get(self, name):
         """ Returns the value of the attribute
@@ -557,8 +589,39 @@ class ResourceManager(Logger):
         :rtype: str
         """
         attr = self._attrs[name]
+        if attr.has_flag(Flags.Global):
+            self.warning( "Attribute %s is global. Use get_global instead." % name)
+            
         return attr.value
 
+    def has_changed(self, name):
+        """ Returns the True is the value of the attribute
+            has been modified by the user.
+
+        :param name: Name of the attribute
+        :type name: str
+        :rtype: str
+        """
+        attr = self._attrs[name]
+        return attr.has_changed()
+
+    def has_flag(self, name, flag):
+        """ Returns true if the attribute has the flag 'flag'
+
+        :param flag: Flag to be checked
+        :type flag: Flags
+        """
+        attr = self._attrs[name]
+        return attr.has_flag(flag)
+
+    def has_attribute(self, name):
+        """ Returns true if the RM has an attribute with name
+
+        :param name: name of the attribute
+        :type name: string
+        """
+        return name in self._attrs
+
     def enable_trace(self, name):
         """ Explicitly enable trace generation
 
@@ -669,6 +732,7 @@ class ResourceManager(Logger):
         connected = []
         rclass = ResourceFactory.get_resource_type(rtype)
         for guid in self.connections:
+
             rm = self.ec.get_resource(guid)
             if not rtype or isinstance(rm, rclass):
                 connected.append(rm)
@@ -699,8 +763,10 @@ class ResourceManager(Logger):
             rm = self.ec.get_resource(guid)
             
             # If one of the RMs this resource needs to wait for has FAILED
-            # we raise an exception
+            # and is critical we raise an exception
             if rm.state == ResourceState.FAILED:
+                if not rm.get('critical'):
+                    continue
                 msg = "Resource can not wait for FAILED RM %d. Setting Resource to FAILED"
                 raise RuntimeError, msg
 
@@ -882,7 +948,7 @@ class ResourceManager(Logger):
                 #for guid in group:
                 #    rm = self.ec.get_resource(guid)
                 #    unmet.append((guid, rm._state))
-                #
+                
                 #self.debug("---- WAITED STATES ---- %s" % unmet )
 
                 reschedule, delay = self._needs_reschedule(group, state, time)
@@ -936,7 +1002,7 @@ class ResourceManager(Logger):
         self.set_ready()
 
     def do_release(self):
-        pass
+        self.set_released()
 
     def do_fail(self):
         self.set_failed()
@@ -944,32 +1010,41 @@ class ResourceManager(Logger):
     def set_started(self):
         """ Mark ResourceManager as STARTED """
         self.set_state(ResourceState.STARTED, "_start_time")
-        
+        self.debug("----- STARTED ---- ")
+
     def set_stopped(self):
         """ Mark ResourceManager as STOPPED """
         self.set_state(ResourceState.STOPPED, "_stop_time")
+        self.debug("----- STOPPED ---- ")
 
     def set_ready(self):
         """ Mark ResourceManager as READY """
         self.set_state(ResourceState.READY, "_ready_time")
+        self.debug("----- READY ---- ")
 
     def set_released(self):
         """ Mark ResourceManager as REALEASED """
         self.set_state(ResourceState.RELEASED, "_release_time")
+        self.debug("----- RELEASED ---- ")
 
     def set_failed(self):
         """ Mark ResourceManager as FAILED """
         self.set_state(ResourceState.FAILED, "_failed_time")
+        self.debug("----- FAILED ---- ")
 
     def set_discovered(self):
         """ Mark ResourceManager as DISCOVERED """
         self.set_state(ResourceState.DISCOVERED, "_discover_time")
+        self.debug("----- DISCOVERED ---- ")
 
     def set_provisioned(self):
         """ Mark ResourceManager as PROVISIONED """
         self.set_state(ResourceState.PROVISIONED, "_provision_time")
+        self.debug("----- PROVISIONED ---- ")
 
     def set_state(self, state, state_time_attr):
+        """ Set the state of the RM while keeping a trace of the time """
+
         # Ensure that RM state will not change after released
         if self._state == ResourceState.RELEASED:
             return 
@@ -1021,7 +1096,7 @@ def find_types():
     path = os.path.dirname(nepi.resources.__file__)
     search_path.add(path)
 
-    types = []
+    types = set()
 
     for importer, modname, ispkg in pkgutil.walk_packages(search_path, 
             prefix = "nepi.resources."):
@@ -1029,7 +1104,7 @@ def find_types():
         loader = importer.find_module(modname)
         
         try:
-            # Notice: Repeated calls to load_module will act as a reload of teh module
+            # Notice: Repeated calls to load_module will act as a reload of the module
             if modname in sys.modules:
                 module = sys.modules.get(modname)
             else:
@@ -1048,7 +1123,7 @@ def find_types():
                     continue
 
                 if issubclass(attr, ResourceManager):
-                    types.append(attr)
+                    types.add(attr)
 
                     if not modname in sys.modules:
                         sys.modules[modname] = module
@@ -1062,4 +1137,3 @@ def find_types():
 
     return types
 
-