Adding linux ns3 server unit test
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Mon, 3 Feb 2014 19:07:34 +0000 (20:07 +0100)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Mon, 3 Feb 2014 19:07:34 +0000 (20:07 +0100)
41 files changed:
setup.py
src/nepi/execution/attribute.py
src/nepi/execution/resource.py
src/nepi/resources/all/collector.py
src/nepi/resources/linux/application.py
src/nepi/resources/linux/ccn/ccncontent.py
src/nepi/resources/linux/ccn/ccnd.py
src/nepi/resources/linux/ccn/ccnping.py
src/nepi/resources/linux/ccn/ccnpingserver.py
src/nepi/resources/linux/ccn/ccnr.py
src/nepi/resources/linux/ccn/fibentry.py
src/nepi/resources/linux/interface.py
src/nepi/resources/linux/mtr.py
src/nepi/resources/linux/node.py
src/nepi/resources/linux/nping.py
src/nepi/resources/linux/ns3/ns3client.py
src/nepi/resources/linux/ns3/ns3simulator.py
src/nepi/resources/linux/ping.py
src/nepi/resources/linux/tcpdump.py
src/nepi/resources/linux/traceroute.py
src/nepi/resources/linux/udptest.py
src/nepi/resources/linux/udptunnel.py
src/nepi/resources/ns3/ns3application.py
src/nepi/resources/ns3/ns3base.py
src/nepi/resources/ns3/ns3channel.py
src/nepi/resources/ns3/ns3ipv4l3protocol.py
src/nepi/resources/ns3/ns3netdevice.py
src/nepi/resources/ns3/ns3node.py
src/nepi/resources/ns3/ns3queue.py
src/nepi/resources/ns3/ns3server.py
src/nepi/resources/ns3/ns3wrapper.py
src/nepi/resources/ns3/resource_manager_generator.py
src/nepi/resources/omf/application.py
src/nepi/resources/planetlab/node.py
src/nepi/resources/planetlab/openvswitch/ovs.py
src/nepi/resources/planetlab/openvswitch/ovsport.py
src/nepi/resources/planetlab/openvswitch/tunnel.py
src/nepi/resources/planetlab/tap.py
src/nepi/util/execfuncs.py
test/resources/linux/ns3/ns3client.py
test/resources/linux/ns3/ns3simulator.py [new file with mode: 0644]

index 27b0f9b..e618057 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -23,6 +23,7 @@ setup(
             "nepi.resources.linux.ns3",
             "nepi.resources.netns",
             "nepi.resources.ns3",
+            "nepi.resources.ns3.classes",
             "nepi.resources.omf",
             "nepi.resources.planetlab",
             "nepi.resources.planetlab.openvswitch",
index 1e3bdde..64a3d05 100644 (file)
@@ -30,18 +30,24 @@ class Flags:
     """ Differents flags to characterize an attribute
 
     """
-    # Attribute can be modified by the user 
-    NoFlags         = 0x00
-    # Attribute is not modifiable by the user
-    ReadOnly        = 0x01
-    # Attribute is not modifiable by the user during runtime
-    ExecReadOnly        = 0x02
-    # Attribute is an access credential
-    # TODO REMOVE!!!
-    Credential      = 0x04
+    # Attribute value can not be read (it is hidden to the user) 
+    NoRead    = 1 # 1
+    
+    # Attribute value can not be modified (it is not editable by the user)
+    NoWrite   = 1 << 1 # 2
+    
+    # Attribute value can be modified only before deployment
+    Design  = 1 << 2 # 4
+
+    # Attribute value will be used only during the deployment face
+    Construct    = 1 << 3 | Design # 8 + 4
+
+    # Attribute provides credentials to access resources
+    Credential  = 1 << 4  | Design # 16 + 4
+
     # Attribute is a filter used to discover resources
-    # TODO REMOVE!!!
-    Filter      = 0x08
+    Filter  = 1 << 5 | Design # 32 + 4
+
 
 class Attribute(object):
     """
@@ -85,12 +91,12 @@ class Attribute(object):
 
     """
     def __init__(self, name, help, type = Types.String,
-            flags = Flags.NoFlags, default = None, allowed = None,
+            flags = None, default = None, allowed = None,
             range = None, set_hook = None):
         self._name = name
         self._help = help
         self._type = type
-        self._flags = flags
+        self._flags = flags or 0
         self._allowed = allowed
         self._range = range
         self._default = self._value = default
@@ -178,3 +184,6 @@ class Attribute(object):
         adequate validation"""
         return True
 
+    def has_changed(self):
+        """ Returns true if the value has changed from the default """
+        return self.value != self.default
index b4a0c88..f0fad39 100644 (file)
@@ -193,7 +193,7 @@ class ResourceManager(Logger):
                 "the experiment. ",
                 type = Types.Bool,
                 default = True,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(critical)
         
@@ -678,6 +678,7 @@ class ResourceManager(Logger):
         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)
         return connected
@@ -1033,7 +1034,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."):
@@ -1041,7 +1042,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:
@@ -1060,10 +1061,7 @@ def find_types():
                     continue
 
                 if issubclass(attr, ResourceManager):
-                    if attr.get_rtype().lower().find("abstract") > -1:
-                        continue 
-
-                    types.append(attr)
+                    types.add(attr)
 
                     if not modname in sys.modules:
                         sys.modules[modname] = module
@@ -1077,4 +1075,3 @@ def find_types():
 
     return types
 
-
index 0b6ad23..f13a392 100644 (file)
@@ -48,14 +48,14 @@ class Collector(ResourceManager):
     @classmethod
     def _register_attributes(cls):
         trace_name = Attribute("traceName", "Name of the trace to be collected", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         store_dir = Attribute("storeDir", "Path to local directory to store trace results", 
                 default = tempfile.gettempdir(),
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         sub_dir = Attribute("subDir", "Sub directory to collect traces into", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         rename = Attribute("rename", "Name to give to the collected trace file", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(trace_name)
         cls._register_attribute(store_dir)
index 5ae8f0b..e287a8a 100644 (file)
@@ -90,43 +90,43 @@ class LinuxApplication(ResourceManager):
         command = Attribute("command", "Command to execute at application start. "
                 "Note that commands will be executed in the ${RUN_HOME} directory, "
                 "make sure to take this into account when using relative paths. ", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         forward_x11 = Attribute("forwardX11", "Enables X11 forwarding for SSH connections", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         env = Attribute("env", "Environment variables string for command execution",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         sudo = Attribute("sudo", "Run with root privileges", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         depends = Attribute("depends", 
                 "Space-separated list of packages required to run the application",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         sources = Attribute("sources", 
                 "Space-separated list of regular files to be uploaded to ${SRC} "
                 "directory prior to building. Archives won't be expanded automatically. "
                 "Sources are globally available for all experiments unless "
                 "cleanHome is set to True (This will delete all sources). ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         files = Attribute("files", 
                 "Space-separated list of regular miscellaneous files to be uploaded "
                 "to ${SHARE} directory. "
                 "Files are globally available for all experiments unless "
                 "cleanHome is set to True (This will delete all files). ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         libs = Attribute("libs", 
                 "Space-separated list of libraries (e.g. .so files) to be uploaded "
                 "to ${LIB} directory. "
                 "Libraries are globally available for all experiments unless "
                 "cleanHome is set to True (This will delete all files). ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         bins = Attribute("bins", 
                 "Space-separated list of binary files to be uploaded "
                 "to ${BIN} directory. "
                 "Binaries are globally available for all experiments unless "
                 "cleanHome is set to True (This will delete all files). ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         code = Attribute("code", 
                 "Plain text source code to be uploaded to the ${APP_HOME} directory. ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         build = Attribute("build", 
                 "Build commands to execute after deploying the sources. "
                 "Sources are uploaded to the ${SRC} directory and code "
@@ -135,16 +135,16 @@ class LinuxApplication(ResourceManager):
                 "./configure && make && make clean.\n"
                 "Make sure to make the build commands return with a nonzero exit "
                 "code on error.",
-                flags = Flags.ReadOnly)
+                flags = Flags.Design)
         install = Attribute("install", 
                 "Commands to transfer built files to their final destinations. "
                 "Install commands are executed after build commands. ",
-                flags = Flags.ReadOnly)
+                flags = Flags.Design)
         stdin = Attribute("stdin", "Standard input for the 'command'", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         tear_down = Attribute("tearDown", "Command to be executed just before " 
                 "releasing the resource", 
-                flags = Flags.ReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(command)
         cls._register_attribute(forward_x11)
index 84f6185..d23ca37 100644 (file)
@@ -34,11 +34,11 @@ class LinuxCCNContent(LinuxApplication):
     def _register_attributes(cls):
         content_name = Attribute("contentName",
                 "The name of the content to publish (e.g. ccn:/VIDEO) ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         content = Attribute("content",
                 "The content to publish. It can be a path to a file or plain text ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         scope = Attribute("scope",
                 "Use the given scope on the start-write request (if -r specified). "
@@ -46,7 +46,7 @@ class LinuxCCNContent(LinuxApplication):
                 "Note that a scope of 3 is encoded as the absence of any scope in the interest. ",
                 type = Types.Integer,
                 default = 1,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(content_name)
         cls._register_attribute(content)
index d8a3fc3..b32937a 100644 (file)
@@ -50,56 +50,56 @@ class LinuxCCND(LinuxApplication):
             "  -1 - max logging \n"
             "  Or apply bitwise OR to these values to get combinations of them",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         port = Attribute("port", "Sets the CCN_LOCAL_PORT environmental variable. "
             "Defaults to 9695 ", 
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
  
         sockname = Attribute("sockname",
             "Sets the CCN_LOCAL_SCOKNAME environmental variable. "
             "Defaults to /tmp/.ccnd.sock", 
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         capacity = Attribute("capacity",
             "Sets the CCND_CAP environmental variable. "
             "Capacity limit in terms of ContentObjects",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         mtu = Attribute("mtu", "Sets the CCND_MTU environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
   
         data_pause = Attribute("dataPauseMicrosec",
             "Sets the CCND_DATA_PAUSE_MICROSEC environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         default_stale = Attribute("defaultTimeToStale",
              "Sets the CCND_DEFAULT_TIME_TO_STALE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         max_stale = Attribute("maxTimeToStale",
             "Sets the CCND_MAX_TIME_TO_STALE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         max_rte = Attribute("maxRteMicrosec",
             "Sets the CCND_MAX_RTE_MICROSEC environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         keystore = Attribute("keyStoreDirectory",
             "Sets the CCND_KEYSTORE_DIRECTORY environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         listen_on = Attribute("listenOn",
             "Sets the CCND_LISTEN_ON environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         autoreg = Attribute("autoreg",
             "Sets the CCND_AUTOREG environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         prefix = Attribute("prefix",
             "Sets the CCND_PREFIX environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(debug)
         cls._register_attribute(port)
index f654a2a..cbe599e 100644 (file)
@@ -34,21 +34,21 @@ class LinuxCCNPing(LinuxCCNPingServer):
         interval = Attribute("i",
             "Set ping interval in seconds (minimum 0.10 second) ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         count = Attribute("c",
             "Total number of pings",
             type = Types.Double,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         number = Attribute("n",
             "Set the starting number, the number is incremented by 1 after each Interest ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
  
         prefix = Attribute("prefix",
             "Prefix to serve content (e.g. ccnx:/name/prefix)",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(interval)
         cls._register_attribute(count)
index 2dee4db..865b104 100644 (file)
@@ -35,16 +35,16 @@ class LinuxCCNPingServer(LinuxCCNApplication):
             "Run ccnping server as a daemon in background",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         freshness = Attribute("x",
             "Set FreshnessSeconds",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         prefix = Attribute("prefix",
             "Prefix to serve content (e.g. ccnx:/name/prefix)",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(daemon)
         cls._register_attribute(freshness)
index e65779a..6b0aa6f 100644 (file)
@@ -35,23 +35,23 @@ class LinuxCCNR(LinuxApplication):
     def _register_attributes(cls):
         max_fanout = Attribute("maxFanout",
             "Sets the CCNR_BTREE_MAX_FANOUT environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         max_leaf_entries = Attribute("maxLeafEntries",
             "Sets the CCNR_BTREE_MAX_LEAF_ENTRIES environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         max_node_bytes = Attribute("maxNodeBytes",
             "Sets the CCNR_BTREE_MAX_NODE_BYTES environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         max_node_pool = Attribute("maxNodePool",
             "Sets the CCNR_BTREE_MAX_NODE_POOL environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         content_cache = Attribute("contentCache",
             "Sets the CCNR_CONTENT_CACHE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         debug = Attribute("debug",
             "Sets the CCNR_DEBUG environmental variable. "
@@ -64,92 +64,92 @@ class LinuxCCNR(LinuxApplication):
                     "WARNING",
                     "INFO",
                     "FINE, FINER, FINEST"],
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         directory = Attribute("directory",
             "Sets the CCNR_DIRECTORY environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         global_prefix = Attribute("globalPrefix",
             "Sets the CCNR_GLOBAL_PREFIX environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         listen_on = Attribute("listenOn",
             "Sets the CCNR_LISTEN_ON environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         min_send_bufsize = Attribute("minSendBufsize",
             "Sets the CCNR_MIN_SEND_BUFSIZE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         proto = Attribute("proto",
             "Sets the CCNR_PROTO environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         status_port = Attribute("statusPort",
             "Sets the CCNR_STATUS_PORT environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         start_write_scope_limit = Attribute("startWriteScopeLimit",
             "Sets the CCNR_START_WRITE_SCOPE_LIMIT environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_debug = Attribute("ccnsDebug",
             "Sets the CCNS_DEBUG environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_enable = Attribute("ccnsEnable",
             "Sets the CCNS_ENABLE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_faux_error = Attribute("ccnsFauxError",
             "Sets the CCNS_FAUX_ERROR environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_heartbeat_micros = Attribute("ccnsHeartBeatMicros",
             "Sets the CCNS_HEART_BEAT_MICROS environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_max_compares_busy = Attribute("ccnsMaxComparesBusy",
             "Sets the CCNS_MAX_COMPARES_BUSY environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_max_fetch_busy = Attribute("ccnsMaxFetchBusy",
             "Sets the CCNS_MAX_FETCH_BUSY environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_node_fetch_lifetime = Attribute("ccnsNodeFetchLifetime",
             "Sets the CCNS_NODE_FETCH_LIFETIME environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_note_err = Attribute("ccnsNoteErr",
             "Sets the CCNS_NOTE_ERR environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_repo_store = Attribute("ccnsRepoStore",
             "Sets the CCNS_REPO_STORE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_root_advise_fresh = Attribute("ccnsRootAdviseFresh",
             "Sets the CCNS_ROOT_ADVISE_FRESH environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_root_advise_lifetime = Attribute("ccnsRootAdviseLifetime",
             "Sets the CCNS_ROOT_ADVISE_LIFETIME environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_stable_enabled = Attribute("ccnsStableEnabled",
             "Sets the CCNS_STABLE_ENABLED environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_sync_scope = Attribute("ccnsSyncScope",
             "Sets the CCNS_SYNC_SCOPE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         repo_file = Attribute("repoFile1",
             "The Repository uses $CCNR_DIRECTORY/repoFile1 for "
             "persistent storage of CCN Content Objects",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(max_fanout)
         cls._register_attribute(max_leaf_entries)
index cebc105..31272f3 100644 (file)
@@ -42,7 +42,7 @@ class LinuxFIBEntry(LinuxApplication):
         uri = Attribute("uri",
                 "URI prefix to match and route for this FIB entry",
                 default = "ccnx:/",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         protocol = Attribute("protocol",
                 "Transport protocol used in network connection to peer "
@@ -50,20 +50,20 @@ class LinuxFIBEntry(LinuxApplication):
                 type = Types.Enumerate, 
                 default = "udp",
                 allowed = ["udp", "tcp"],
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         host = Attribute("host",
                 "Peer hostname used in network connection for this FIB entry. ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         port = Attribute("port",
                 "Peer port address used in network connection to peer "
                 "for this FIB entry.",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         ip = Attribute("ip",
                 "Peer host public IP used in network connection for this FIB entry. ",
-                flags = Flags.ReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(uri)
         cls._register_attribute(protocol)
index 7b8eadc..795c4d5 100644 (file)
@@ -42,33 +42,33 @@ class LinuxInterface(ResourceManager):
     @classmethod
     def _register_attributes(cls):
         ip4 = Attribute("ip4", "IPv4 Address",
-              flags = Flags.ExecReadOnly)
+              flags = Flags.Design)
 
         ip6 = Attribute("ip6", "IPv6 Address",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         mac = Attribute("mac", "MAC Address",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         mask4 = Attribute("mask4", "IPv4 network mask",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         mask6 = Attribute("mask6", "IPv6 network mask",
                 type = Types.Integer,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         mtu = Attribute("mtu", "Maximum transmition unit for device",
                 type = Types.Integer)
 
         devname = Attribute("deviceName", 
                 "Name of the network interface (e.g. eth0, wlan0, etc)",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         up = Attribute("up", "Link up", type = Types.Bool)
 
         tear_down = Attribute("tearDown", "Bash script to be executed before " + \
                 "releasing the resource",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(ip4)
         cls._register_attribute(ip6)
index 1edc6b5..b694443 100644 (file)
@@ -34,41 +34,41 @@ class LinuxMtr(LinuxApplication):
             "sets mtr --report-cycles (-c) option. Determines the number of "
             "pings sent to determine both machines in the networks. Each "
             "cycle lasts one sencond.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         no_dns = Attribute("noDns",
             "sets mtr --no-dns (-n) option. Forces mtr to display IPs intead of "
             "trying to resolve to host names ",
             type = Types.Bool,
             default = True,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         address = Attribute("address",
             "sets mtr --address (-a) option. Binds the socket to send outgoing "
             "packets to the interface of the specified address, so that any "
             "any packets are sent through this interface. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         interval = Attribute("interval",
             "sets mtr --interval (-i) option. Specifies the number of seconds "
             "between ICMP ECHO requests. Default value is one second ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         countinuous = Attribute("continuous",
             "Run mtr in a while loop",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         print_timestamp = Attribute("printTimestamp",
             "Print timestamp before running mtr",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         target = Attribute("target",
             "mtr target host (host that will be pinged)",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(report_cycles)
         cls._register_attribute(no_dns)
index 710561b..4e162ce 100644 (file)
@@ -149,44 +149,44 @@ class LinuxNode(ResourceManager):
     @classmethod
     def _register_attributes(cls):
         hostname = Attribute("hostname", "Hostname of the machine",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         username = Attribute("username", "Local account username", 
                 flags = Flags.Credential)
 
-        port = Attribute("port", "SSH port", flags = Flags.ExecReadOnly)
+        port = Attribute("port", "SSH port", flags = Flags.Design)
         
         home = Attribute("home",
                 "Experiment home directory to store all experiment related files",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         
         identity = Attribute("identity", "SSH identity file",
                 flags = Flags.Credential)
         
         server_key = Attribute("serverKey", "Server public key", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         
         clean_home = Attribute("cleanHome", "Remove all nepi files and directories "
                 " from node home folder before starting experiment", 
                 type = Types.Bool,
                 default = False,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         clean_experiment = Attribute("cleanExperiment", "Remove all files and directories " 
                 " from a previous same experiment, before the new experiment starts", 
                 type = Types.Bool,
                 default = False,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         
         clean_processes = Attribute("cleanProcesses", 
                 "Kill all running processes before starting experiment",
                 type = Types.Bool,
                 default = False,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         
         tear_down = Attribute("tearDown", "Bash script to be executed before " + \
                 "releasing the resource",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(hostname)
         cls._register_attribute(username)
index 62bacd8..544b4d9 100644 (file)
@@ -34,84 +34,84 @@ class LinuxNPing(LinuxApplication):
             "Sets nping -c option. "
             "Stop after a given number of rounds. ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         e = Attribute("e",
             "Sets nping -e option. "
             "Set the network interface to be used.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         delay = Attribute("delay",
             "Sets nping --delay option. "
             "Delay between probes ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         rate = Attribute("rate",
             "Sets nping --rate option. "
             "Send probes at a given rate ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ttl = Attribute("ttl",
             "Sets nping --ttl option. "
             "Time To Live. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         p = Attribute("p",
             "Sets nping -p option. "
             "Target ports. ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         tcp = Attribute("tcp",
             "Sets nping --tcp option. "
             "TCP mode. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         udp = Attribute("udp",
             "Sets nping --udp option. "
             "UDP mode. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         icmp = Attribute("icmp",
             "Sets nping --icmp option. "
             "ICMP mode. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         arp = Attribute("arp",
             "Sets nping --arp option. "
             "ARP mode. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         traceroute = Attribute("traceroute",
             "Sets nping --traceroute option. "
             "Traceroute mode. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         countinuous = Attribute("continuous",
             "Run nping in a while loop",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         print_timestamp = Attribute("printTimestamp",
             "Print timestamp before running nping",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         target = Attribute("target",
             "nping target host (host that will be pinged)",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(c)
         cls._register_attribute(e)
index 972e800..3fe5b99 100644 (file)
@@ -58,6 +58,12 @@ class LinuxNS3Client(NS3Client):
         
         return self.send_msg(NS3WrapperMessage.CREATE, *args)
 
+    def factory(self, type_name, **kwargs):
+        args = [type_name]
+        args.append(kwargs)
+        
+        return self.send_msg(NS3WrapperMessage.FACTORY, *args)
+
     def invoke(self, uuid, operation, *args):
         args = list(args)
         args.insert(0, operation)
index e4fda7e..90edbc5 100644 (file)
@@ -22,7 +22,6 @@ from nepi.execution.trace import Trace, TraceAttr
 from nepi.execution.resource import ResourceManager, clsinit_copy, \
         ResourceState, reschedule_delay
 from nepi.resources.linux.application import LinuxApplication
-from nepi.resources.linux.node import OSType
 from nepi.util.timefuncs import tnow, tdiffsec
 from nepi.resources.ns3.ns3simulator import NS3Simulator
 from nepi.resources.linux.ns3.ns3client import LinuxNS3Client
@@ -35,21 +34,18 @@ class LinuxNS3Simulator(LinuxApplication, NS3Simulator):
 
     @classmethod
     def _register_attributes(cls):
-        max_rte = Attribute("maxRteMicrosec",
-            "Sets the CCND_MAX_RTE_MICROSEC environmental variable. ",
-            flags = Flags.ExecReadOnly)
+        socket_name = Attribute("socketName",
+            "Local socket name to communicate with the ns-3 server ",
+            flags = Flags.Design)
 
-        cls._register_attribute(max_rte)
+        cls._register_attribute(socket_name)
 
     def __init__(self, ec, guid):
         super(LinuxApplication, self).__init__(ec, guid)
         super(NS3Simulator, self).__init__()
 
+        self._client = None
         self._home = "ns3-simu-%s" % self.guid
-        
-        # TODO: Create socket!!
-        self._client = LinuxNS3Client(socket_name)
-
 
     def do_deploy(self):
         if not self.node or self.node.state < ResourceState.READY:
@@ -58,212 +54,14 @@ class LinuxNS3Simulator(LinuxApplication, NS3Simulator):
             # ccnd needs to wait until node is deployed and running
             self.ec.schedule(reschedule_delay, self.deploy)
         else:
-            if not self.get("command"):
-                self.set("command", self._start_command)
             
-            if not self.get("depends"):
-                self.set("depends", self._dependencies)
-
-            if not self.get("sources"):
-                self.set("sources", self._sources)
-
-            sources = self.get("sources")
-            source = sources.split(" ")[0]
-            basename = os.path.basename(source)
-            self._version = ( basename.strip().replace(".tar.gz", "")
-                    .replace(".tar","")
-                    .replace(".gz","")
-                    .replace(".zip","") )
-
-            if not self.get("build"):
-                self.set("build", self._build)
-
-            if not self.get("install"):
-                self.set("install", self._install)
+            # TODO: Create socket!!
+            socket_name = self.get("socketName")
+            self._client = LinuxNS3Client(socket_name)
 
-            if not self.get("env"):
-                self.set("env", self._environment)
-
-            command = self.get("command")
-
-            self.info("Deploying command '%s' " % command)
-
-            self.do_discover()
-            self.do_provision()
+            #self.do_discover()
+            #self.do_provision()
 
             self.debug("----- READY ---- ")
             self.set_ready()
 
-    def upload_start_command(self):
-        command = self.get("command")
-        env = self.get("env")
-
-        # We want to make sure the ccnd is running
-        # before the experiment starts.
-        # Run the command as a bash script in background,
-        # in the host ( but wait until the command has
-        # finished to continue )
-        env = self.replace_paths(env)
-        command = self.replace_paths(command)
-
-        shfile = os.path.join(self.app_home, "start.sh")
-        self.node.run_and_wait(command, self.run_home,
-                shfile = shfile,
-                overwrite = False,
-                env = env,
-                raise_on_error = True)
-
-    def do_start(self):
-        if self.state == ResourceState.READY:
-            command = self.get("command")
-            self.info("Starting command '%s'" % command)
-
-            self.set_started()
-        else:
-            msg = " Failed to execute command '%s'" % command
-            self.error(msg, out, err)
-            raise RuntimeError, msg
-
-    def do_stop(self):
-        command = self.get('command') or ''
-        
-        if self.state == ResourceState.STARTED:
-            self.info("Stopping command '%s'" % command)
-
-            command = "ccndstop"
-            env = self.get("env") 
-
-            # replace application specific paths in the command
-            command = self.replace_paths(command)
-            env = env and self.replace_paths(env)
-
-            # Upload the command to a file, and execute asynchronously
-            shfile = os.path.join(self.app_home, "stop.sh")
-            self.node.run_and_wait(command, self.run_home,
-                        shfile = shfile,
-                        overwrite = False,
-                        env = env,
-                        pidfile = "ccndstop_pidfile", 
-                        ecodefile = "ccndstop_exitcode", 
-                        stdout = "ccndstop_stdout", 
-                        stderr = "ccndstop_stderr")
-
-            self.set_stopped()
-    
-    @property
-    def state(self):
-        # First check if the ccnd has failed
-        state_check_delay = 0.5
-        if self._state == ResourceState.STARTED and \
-                tdiffsec(tnow(), self._last_state_check) > state_check_delay:
-            (out, err), proc = self._ccndstatus()
-
-            retcode = proc.poll()
-
-            if retcode == 1 and err.find("No such file or directory") > -1:
-                # ccnd is not running (socket not found)
-                self.set_stopped()
-            elif retcode:
-                # other errors ...
-                msg = " Failed to execute command '%s'" % self.get("command")
-                self.error(msg, out, err)
-                self.fail()
-
-            self._last_state_check = tnow()
-
-        return self._state
-
-    def _ccndstatus(self):
-        env = self.get('env') or ""
-        environ = self.node.format_environment(env, inline = True)
-        command = environ + " ccndstatus"
-        command = self.replace_paths(command)
-    
-        return self.node.execute(command)
-
-    @property
-    def _start_command(self):
-        return "ccndstart"
-
-    @property
-    def _dependencies(self):
-        if self.node.use_rpm:
-            return ( " autoconf openssl-devel  expat-devel libpcap-devel "
-                " ecryptfs-utils-devel libxml2-devel automake gawk " 
-                " gcc gcc-c++ git pcre-devel make ")
-        elif self.node.use_deb:
-            return ( " autoconf libssl-dev libexpat-dev libpcap-dev "
-                " libecryptfs0 libxml2-utils automake gawk gcc g++ "
-                " git-core pkg-config libpcre3-dev make ")
-        return ""
-
-    @property
-    def _sources(self):
-        return "http://www.ccnx.org/releases/ccnx-0.7.2.tar.gz"
-
-    @property
-    def _build(self):
-        sources = self.get("sources").split(" ")[0]
-        sources = os.path.basename(sources)
-
-        return (
-            # Evaluate if ccnx binaries are already installed
-            " ( "
-                " test -f ${BIN}/%(version)s/ccnd && "
-                " echo 'binaries found, nothing to do' "
-            " ) || ( "
-            # If not, untar and build
-                " ( "
-                    " mkdir -p ${SRC}/%(version)s && "
-                    " tar xf ${SRC}/%(sources)s --strip-components=1 -C ${SRC}/%(version)s "
-                 " ) && "
-                    "cd ${SRC}/%(version)s && "
-                    # Just execute and silence warnings...
-                    " ( ./configure && make ) "
-             " )") % ({ 'sources': sources,
-                        'version': self.version
-                 })
-
-    @property
-    def _install(self):
-        return (
-            # Evaluate if ccnx binaries are already installed
-            " ( "
-                " test -f ${BIN}/%(version)s/ccnd && "
-                " echo 'binaries found, nothing to do' "
-            " ) || ( "
-            # If not, install
-                "  mkdir -p ${BIN}/%(version)s && "
-                "  mv ${SRC}/%(version)s/bin/* ${BIN}/%(version)s/ "
-            " )"
-            ) % ({ 'version': self.version
-                 })
-
-    @property
-    def _environment(self):
-        envs = dict({
-            "debug": "CCND_DEBUG",
-            "port": "CCN_LOCAL_PORT",
-            "sockname" : "CCN_LOCAL_SOCKNAME",
-            "capacity" : "CCND_CAP",
-            "mtu" : "CCND_MTU",
-            "dataPauseMicrosec" : "CCND_DATA_PAUSE_MICROSEC",
-            "defaultTimeToStale" : "CCND_DEFAULT_TIME_TO_STALE",
-            "maxTimeToStale" : "CCND_MAX_TIME_TO_STALE",
-            "maxRteMicrosec" : "CCND_MAX_RTE_MICROSEC",
-            "keyStoreDirectory" : "CCND_KEYSTORE_DIRECTORY",
-            "listenOn" : "CCND_LISTEN_ON",
-            "autoreg" : "CCND_AUTOREG",
-            "prefix" : "CCND_PREFIX",
-            })
-
-        env = self.path 
-        env += " ".join(map(lambda k: "%s=%s" % (envs.get(k), str(self.get(k))) \
-            if self.get(k) else "", envs.keys()))
-        
-        return env            
-
-    def valid_connection(self, guid):
-        # TODO: Validate!
-        return True
-
index 6db0a8d..a3df579 100644 (file)
@@ -34,56 +34,56 @@ class LinuxPing(LinuxApplication):
             "Sets ping -c option. Determines the number of ECHO_REQUEST "
             "packates to send before stopping.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         mark = Attribute("mark",
             "Sets ping -m option. Uses 'mark' to tag outgoing packets. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         interval = Attribute("interval",
             "Sets ping -i option. Leaves interval seconds between "
             "successive ECHO_REUQEST packets. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         address = Attribute("address",
             "Sets ping -I option. Sets ECHO_REQUEST packets souce address "
             "to the specified interface address ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         preload = Attribute("preload",
             "Sets ping -l option. Sends preload amount of packets "
             "without waiting for a reply ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         numeric = Attribute("numeric",
             "Sets ping -n option. Disables resolution of host addresses into "
             "symbolic names. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         pattern = Attribute("pattern",
             "Sets ping -p option. Species a up to 16 ''pad'' bytes to fill "
             "out sent packets. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         printtmp = Attribute("printTimestamp",
             "Sets ping -D option. Prints timestamp befor each line as: "
             "unix time + microseconds as in gettimeofday ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         tos = Attribute("tos",
             "Sets ping -Q option. Sets Quality of Service related bits in ICMP "
             "datagrams. tos can be either a decimal or hexadecime number ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         quiet = Attribute("quiet",
             "Sets ping -q option. Disables ping standard output ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         rec_route = Attribute("recordRoute",
             "Sets ping -R option. Includes the RECORD_ROUTE option in the "
@@ -91,37 +91,37 @@ class LinuxPing(LinuxApplication):
             "ping standard output.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         route_bypass = Attribute("routeBypass",
             "Sets ping -r option. Bypasses normal routing tables and sends "
             "ECHO REQUEST packets directly yo a host on an attached interface. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         packetsize = Attribute("packetSize",
             "Sets ping -s option. Specifies the number of data bytes to be "
             "sent. Defaults to 56. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         sendbuff = Attribute("sendBuff",
             "Sets ping -S option. Specifies the number of packets to buffer. "
             "Defaults to one. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ttl = Attribute("ttl",
             "Sets ping -t option. Specifies the IP Time to Live for the "
             "packets. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         timestamp = Attribute("timestamp",
             "Sets ping -T option. Sets special IP timestamp options. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         hint = Attribute("hint",
             "Sets ping -M option. Selects Path MTU Discovery strategy. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         full_latency = Attribute("fullLatency",
             "Sets ping -U option. Calculates round trip time taking into "
@@ -129,32 +129,32 @@ class LinuxPing(LinuxApplication):
             "network round trip time. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         verbose = Attribute("verbose",
             "Sets ping -v option. Verbose output. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         flood = Attribute("flood",
             "Sets ping -f option. Flood ping. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         deadline = Attribute("deadline",
             "Sets ping -w option. Specify a timeout, in seconds, before ping "
             "exits regardless of how many packets have been sent or received.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         timeout = Attribute("timeout",
             "Sets ping -W option. Time to wait for a respone in seconds .",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         target = Attribute("target",
             "The host to ping .",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(count)
         cls._register_attribute(mark)
index 12d11a2..761c03e 100644 (file)
@@ -35,25 +35,25 @@ class LinuxTcpdump(LinuxApplication):
             "Prints each packet (minus its link level header) in ASCII.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         b = Attribute("b",
             "Sets tcpdump -b option. "
             "Prints the AS number in BGP packets in ASDOT notation. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         B = Attribute("B",
             "Sets tcpdump -B option. "
             "Sets the operaing system capture buffer size in untils of "
             "KiB (1024 bytes).",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         c = Attribute("c",
             "Sets tcpdump -c option. "
             "Exists after receiving count packets.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         C = Attribute("C",
             "Sets tcpdump -C option. "
@@ -63,7 +63,7 @@ class LinuxTcpdump(LinuxApplication):
             "Savefiles after the first savefile will have the name specified "
             "with the -w with a number after it, starting at 1 and continuing "
             "upward. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         d = Attribute("d",
             "Sets tcpdump -d option. "
@@ -71,14 +71,14 @@ class LinuxTcpdump(LinuxApplication):
             "to standard output and stop.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         dd = Attribute("dd",
             "Sets tcpdump -dd option. "
             "Dump packet-matching code as a C program fragment. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ddd = Attribute("ddd",
             "Sets tcpdump -ddd option. "
@@ -86,7 +86,7 @@ class LinuxTcpdump(LinuxApplication):
             "(preceded with a count).",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         D = Attribute("D",
             "Sets tcpdump -D option. "
@@ -94,19 +94,19 @@ class LinuxTcpdump(LinuxApplication):
             "and on which tcpdump can capture packets. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         e = Attribute("e",
             "Sets tcpdump -e option. "
             "Print the link-level header on each dump line.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         F =  Attribute("F",
             "Sets tcpdump -F option. "
             "Use file as input for the filter expression.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         G =  Attribute("G",
             "Sets tcpdump -G option. "
@@ -114,14 +114,14 @@ class LinuxTcpdump(LinuxApplication):
             "option every rotate_seconds seconds. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         i =  Attribute("i",
             "Sets tcpdump -i option. "
             "Listen on interface.  If unspecified, tcpdump searches the "
             "system interface list for the lowest  numbered, configured "
             "up interface (excluding loopback). ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         I =  Attribute("I",
             "Sets tcpdump -I option. "
@@ -130,7 +130,7 @@ class LinuxTcpdump(LinuxApplication):
             "operating systems. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         j = Attribute("j",
             "Sets tcpdump -j option. "
@@ -138,21 +138,21 @@ class LinuxTcpdump(LinuxApplication):
             "The names to use for the time stamp types are given in "
             "pcap-tstamp-type(7); not all the types listed there will "
             "necessarily be valid for any given interface.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         K = Attribute("K",
             "Sets tcpdump -K option. "
             "Don't attempt to verify IP, TCP, or UDP checksums. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         l = Attribute("l",
             "Sets tcpdump -l option. "
             "Make stdout line buffered. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         U = Attribute("U",
             "Sets tcpdump -U option. "
@@ -161,7 +161,7 @@ class LinuxTcpdump(LinuxApplication):
             "at the end of each packet. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         n = Attribute("n",
             "Sets tcpdump -n option. "
@@ -169,7 +169,7 @@ class LinuxTcpdump(LinuxApplication):
             "etc.) to names.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         N = Attribute("N",
             "Sets tcpdump -N option. "
@@ -178,20 +178,20 @@ class LinuxTcpdump(LinuxApplication):
             "instead of ``nic.ddn.mil''.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         S = Attribute("S",
             "Sets tcpdump -S option. "
             "Print absolute, rather than relative, TCP sequence numbers.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         s = Attribute("s",
             "Sets tcpdump -s option. "
             "Snarf  snaplen bytes of data from each packet rather than "
             "the default of 65535 bytes. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         T = Attribute("T",
             "Sets tcpdump -T option. "
@@ -203,21 +203,21 @@ class LinuxTcpdump(LinuxApplication):
              "protocol), snmp (Simple Network Management Protocol), tftp "
              "(Trivial  File Transfer Protocol), vat (Visual Audio Tool), "
              "and wb (distributed White Board).",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         t = Attribute("t",
             "Sets tcpdump -t option. "
             "Don't print a timestamp on each dump line.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         tt = Attribute("tt",
             "Sets tcpdump -tt option. "
             "Print an unformatted timestamp on each dump line. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ttt = Attribute("ttt",
             "Sets tcpdump -ttt option. "
@@ -225,7 +225,7 @@ class LinuxTcpdump(LinuxApplication):
             "and previous line on each dump line.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         tttt = Attribute("tttt",
             "Sets tcpdump -tttt option. "
@@ -233,7 +233,7 @@ class LinuxTcpdump(LinuxApplication):
             "each dump line. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ttttt = Attribute("ttttt",
             "Sets tcpdump -ttttt option. "
@@ -241,7 +241,7 @@ class LinuxTcpdump(LinuxApplication):
             "first line on each dump line.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         v = Attribute("v",
             "Sets tcpdump -v option. "
@@ -249,21 +249,21 @@ class LinuxTcpdump(LinuxApplication):
             "verbose output. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         vv = Attribute("vv",
             "Sets tcpdump -vv option. "
             "Even  more  verbose  output. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         vvv = Attribute("vvv",
             "Sets tcpdump -vv option. "
             "Even  more  verbose  output. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         w = Attribute("w",
             "Sets tcpdump -w option. "
@@ -271,11 +271,11 @@ class LinuxTcpdump(LinuxApplication):
             "and printing them out.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         expression = Attribute("expression",
             "selects  which packets will be dumped.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(A)
         cls._register_attribute(b)
index 99eea6b..5e592a8 100644 (file)
@@ -35,13 +35,13 @@ class LinuxTraceroute(LinuxApplication):
             "Run traceroute in a while loop",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         print_timestamp = Attribute("printTimestamp",
             "Print timestamp before running traceroute",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         use_ip = Attribute("useIP",
             "Use the IP address instead of the host domain name. "
@@ -49,11 +49,11 @@ class LinuxTraceroute(LinuxApplication):
             "frequently",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         target = Attribute("target",
             "Traceroute target host (host that will be pinged)",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(countinuous)
         cls._register_attribute(print_timestamp)
index 76c5914..46accbc 100644 (file)
@@ -40,103 +40,103 @@ class LinuxUdpTest(LinuxApplication):
             "Runs in server mode. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         p = Attribute("p",
             "Port to listen to in server mode, or to connect to in client mode. "
             "Defaults to 5678. ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         a = Attribute("a",
             "Client option. Perform UDP Round Trip Time (latency) ",
             type = Types.Bool,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         A = Attribute("A",
             "Client option. "
             "Message size for UDP RTT test. "
             "UDP RTT (latency) test with specified message size.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         b = Attribute("b",
             "Client option. "
             "Client UDP buffer size in bytes. Using system default "
             "value if not defined.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         B = Attribute("B",
             "Client option. "
             "Server UDP buffer size in bytes. The same as cleint's by default.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         c = Attribute("c",
             "Client option. "
             "CPU log option. Tracing system info during the test. "
             "Only available when output is defined. ",
             type = Types.Bool,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         d = Attribute("d",
             "Client option. "
             "Data size of each read/write in bytes. The same as packet size "
             "by default.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         e = Attribute("e",
             "Client option. "
             "Exponential test (data size of each sending increasing from 1 "
             "byte to packet size). ",
             type = Types.Bool,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         g = Attribute("g",
             "Client option. "
             "UDP traffic generator (Keep sending data to a host). "
             "Work without server's support.",
             type = Types.Bool,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         target = Attribute("target",
             "Client option. "
             "Hostname or IP address of UDP server. Must be specified.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         i = Attribute("i",
             "Client option. "
             "Bidirectional UDP throuhgput test. Default is unidirection "
             "stream test. ",
             type = Types.Bool,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         l = Attribute("l",
             "Client option. "
             "UDP datagram (packet) size in bytes ( < udp-buffer-szie ). "
             "1460 by default.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         m = Attribute("m",
             "Client option. "
             "Total message size in bytes. 1048576 by default.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         o = Attribute("o",
             "Client option. "
             "Output file name. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         P = Attribute("P",
             "Client option. "
             "Write the plot file for gnuplot. Only enable when the output "
             "is specified. ",
             type = Types.Bool,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         q = Attribute("q",
             "Client option. "
@@ -152,38 +152,38 @@ class LinuxUdpTest(LinuxApplication):
             "is specified. ",
             type = Types.Enumerate,
             allowed = ["1", "2", "3", "4", "5", "6"],
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         r = Attribute("r",
             "Client option. "
             "Repetition of tests. 10 by default. ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         t = Attribute("t",
             "Client option. "
             "Test time constraint in seconds. 5 by default. ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         T = Attribute("T",
             "Client option. "
             "Throughput constraint for UDP generator or throughput "
             "test. Unlimited by default. ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         continuous = Attribute("continuous",
             "Run nping in a while loop",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         print_timestamp = Attribute("printTimestamp",
             "Print timestamp before running nping",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(s)
         cls._register_attribute(p)
index 6372729..44edad6 100644 (file)
@@ -43,25 +43,25 @@ class UdpTunnel(LinuxApplication):
                 default = None,
                 allowed = ["PLAIN", "AES", "Blowfish", "DES", "DES3"],
                 type = Types.Enumerate, 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cipher_key = Attribute("cipherKey",
                 "Specify a symmetric encryption key with which to protect "
                 "packets across the tunnel. python-crypto must be installed "
                 "on the system." ,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         txqueuelen = Attribute("txQueueLen",
                 "Specifies the interface's transmission queue length. "
                 "Defaults to 1000. ", 
                 type = Types.Integer, 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         bwlimit = Attribute("bwLimit",
                 "Specifies the interface's emulated bandwidth in bytes "
                 "per second.",
                 type = Types.Integer, 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(cipher)
         cls._register_attribute(cipher_key)
index f53d505..6f8ad6b 100644 (file)
@@ -30,3 +30,24 @@ class NS3BaseApplication(NS3Base):
             self.simulator.invoke(node.uuid, "AddApplication", self.uuid)
             self._connected.add(node.uuid)
 
+    def do_start(self):
+        if self.state == ResourceState.READY:
+            self.info("Starting")
+
+            # BUG: without doing this explicit call it doesn't start!!!
+            # Shouldn't be enough to set the StartTime?
+            self.simulator.invoke(self.uuid, "Start")
+            
+            self.set_started()
+        else:
+            msg = " Failed "
+            self.error(msg, out, err)
+            raise RuntimeError, msg
+
+    def do_stop(self):
+        if self.state == ResourceState.STARTED:
+            # No need to do anything, simulator.Destroy() will stop every object
+            self.info("Stopping command '%s'" % command)
+            self.simulator.invoke(self.uuid, "Stop")
+            self.set_stopped()
+
index f36ffce..ba03596 100644 (file)
@@ -21,15 +21,14 @@ from nepi.execution.resource import ResourceManager, clsinit_copy, \
         ResourceState, reschedule_delay
 
 from nepi.execution.attribute import Flags
-from nepi.resources.ns3.ns3simulator import NS3Simulator
 
 @clsinit_copy
 class NS3Base(ResourceManager):
     _rtype = "abstract::ns3::Object"
     _backend_type = "ns3"
 
-    def __init__(self):
-        super(NS3Base, self).__init__()
+    def __init__(self, ec, guid):
+        super(NS3Base, self).__init__(ec, guid)
         self._uuid = None
         self._connected = set()
 
@@ -43,10 +42,7 @@ class NS3Base(ResourceManager):
 
     @property
     def simulator(self):
-        simulators = self.get_connected(NS3Simulator.get_rtype())
-        if simulators: return simulators[0]
-        # if the object is not directly connected to the simulator,
-        # it should be connected to a node
+        # Ns3 RMs should be connected to the simulator through a ns3 node 
         node = self.node
         if node: return node.simulator
         return None
@@ -70,13 +66,13 @@ class NS3Base(ResourceManager):
             return 
 
         kwargs = dict()
-        for attr in self._attrs:
-            if not attr.value or attr.has_flag(Flags.ReadOnly):
+        for attr in self._attrs.values():
+            if not (attr.has_changed() and attr.has_flag(Flags.Construct)):
                 continue
 
             kwargs[attr.name] = attr.value
 
-        self.uuid = self.simulator.factory(self.get_rtype(), **kwargs)
+        self._uuid = self.simulator.factory(self.get_rtype(), **kwargs)
 
     def _configure_object(self):
         pass
index 063e31b..7386346 100644 (file)
@@ -32,6 +32,6 @@ class NS3BaseChannel(NS3Base):
     @property
     def simulator(self):
         devices = self.devices
-        if devices: return device[0].node.simulator
+        if devices: return devices[0].node.simulator
         return None
     
index 2155422..67fe21d 100644 (file)
@@ -25,9 +25,11 @@ class NS3BaseIpv4L3Protocol(NS3Base):
     _rtype = "abstract::ns3::Ipv4L3Protocol"
 
     def _configure_object(self):
+        simulator = self.simulator
+
         uuid_list_routing = simulator.create("Ipv4ListRouting")
         simulator.invoke(self.uuid, "SetRoutingProtocol", uuid_list_routing)
 
         uuid_static_routing = simulator.create("Ipv4StaticRouting")
-        simulator.invoke(self.uuid, "SetRoutingProtocol", uuid_static_routing, 1)
+        simulator.invoke(uuid_list_routing, "AddRoutingProtocol", uuid_static_routing, 1)
 
index 4978c7e..009d14c 100644 (file)
@@ -21,6 +21,8 @@ from nepi.execution.attribute import Attribute, Flags
 from nepi.execution.resource import clsinit_copy
 from nepi.resources.ns3.ns3base import NS3Base
 
+import ipaddr
+
 @clsinit_copy
 class NS3BaseNetDevice(NS3Base):
     _rtype = "abstract::ns3::NetDevice"
@@ -28,13 +30,13 @@ class NS3BaseNetDevice(NS3Base):
     @classmethod
     def _register_attributes(cls):
         mac = Attribute("mac", "MAC address for device",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         ip = Attribute("ip", "IP address for device",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         prefix = Attribute("prefix", "Network prefix for device",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(mac)
         cls._register_attribute(ip)
@@ -42,7 +44,7 @@ class NS3BaseNetDevice(NS3Base):
 
     @property
     def channel(self):
-        from nepi.resources.ns3.ns3channel import NS3Channel
+        from nepi.resources.ns3.ns3channel import NS3BaseChannel
         channels = self.get_connected(NS3BaseChannel.get_rtype())
         if channels: return channels[0]
         return None
index 7d0380c..0cecfa7 100644 (file)
 
 from nepi.execution.resource import clsinit_copy
 from nepi.resources.ns3.ns3base import NS3Base
+from nepi.resources.ns3.ns3simulator import NS3Simulator
 
 @clsinit_copy
 class NS3BaseNode(NS3Base):
     _rtype = "abstract::ns3::Node"
 
+    @property
+    def simulator(self):
+        for guid in self.connections:
+            rm = self.ec.get_resource(guid)
+            if isinstance(rm, NS3Simulator):
+                return rm
+
+        return None
+
     @property
     def ipv4(self):
         from nepi.resources.ns3.ns3ipv4l3protocol import NS3BaseIpv4L3Protocol
index 55ed57f..a02a96e 100644 (file)
@@ -26,7 +26,7 @@ class NS3BaseQueue(NS3Base):
 
     @property
     def device(self):
-        from nepi.resources.ns3.ns3device import NS3BaseNetDevice
+        from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice
         devices = self.get_connected(NS3BaseNetDevice.get_rtype())
         if devices: return devices[0]
         return None
index b6df768..9e3920f 100644 (file)
 import base64
 import cPickle
 import errno
+import logging
+import os
 import socket
+
 from optparse import OptionParser, SUPPRESS_HELP
 
 from ns3wrapper import NS3Wrapper
@@ -39,6 +42,9 @@ class NS3WrapperMessage:
 def handle_message(ns3_wrapper, msg, args):
     if msg == NS3WrapperMessage.SHUTDOWN:
         ns3_wrapper.shutdown()
+        
+        ns3_wrapper.logger.debug("SHUTDOWN")
+        
         return "BYEBYE"
     
     if msg == NS3WrapperMessage.STOP:
@@ -46,16 +52,22 @@ def handle_message(ns3_wrapper, msg, args):
         if args:
             time = args[0]
 
+        ns3_wrapper.logger.debug("STOP time=%s" % str(time))
+
         ns3_wrapper.stop(time=time)
         return "STOPPED"
 
     if msg == NS3WrapperMessage.START:
+        ns3_wrapper.logger.debug("START") 
+
         ns3_wrapper.start()
         return "STARTED"
 
     if msg == NS3WrapperMessage.CREATE:
         clazzname = args.pop(0)
         
+        ns3_wrapper.logger.debug("CREATE %s %s" % (clazzname, str(args)))
+
         uuid = ns3_wrapper.create(clazzname, *args)
         return uuid
 
@@ -63,6 +75,8 @@ def handle_message(ns3_wrapper, msg, args):
         type_name = args.pop(0)
         kwargs = args.pop(0)
 
+        ns3_wrapper.logger.debug("FACTORY %s %s" % (type_name, str(kwargs)))
+
         uuid = ns3_wrapper.factory(type_name, **kwargs)
         return uuid
 
@@ -70,6 +84,8 @@ def handle_message(ns3_wrapper, msg, args):
         uuid = args.pop(0)
         operation = args.pop(0)
         
+        ns3_wrapper.logger.debug("INVOKE %s %s %s" % (uuid, operation, str(args)))
+    
         uuid = ns3_wrapper.invoke(uuid, operation, *args)
         return uuid
 
@@ -77,6 +93,8 @@ def handle_message(ns3_wrapper, msg, args):
         uuid = args.pop(0)
         name = args.pop(0)
 
+        ns3_wrapper.logger.debug("GET %s %s" % (uuid, name))
+
         value = ns3_wrapper.get(uuid, name)
         return value
 
@@ -85,10 +103,13 @@ def handle_message(ns3_wrapper, msg, args):
         name = args.pop(0)
         value = args.pop(0)
 
+        ns3_wrapper.logger.debug("SET %s %s" % (uuid, name, str(value)))
+
         value = ns3_wrapper.set(uuid, name, value)
         return value
  
     if msg == NS3WrapperMessage.TRACE:
+        ns3_wrapper.logger.debug("TRACE") 
         return "NOT IMPLEMENTED"
 
 def create_socket(socket_name):
@@ -135,7 +156,7 @@ def send_reply(conn, reply):
     conn.send("%s\n" % encoded)
 
 def get_options():
-    usage = ("usage: %prog -S <socket-name>")
+    usage = ("usage: %prog -S <socket-name> -L <NS_LOG> -v ")
     
     parser = OptionParser(usage = usage)
 
@@ -143,12 +164,30 @@ def get_options():
         help = "Name for the unix socket used to interact with this process", 
         default = "tap.sock", type="str")
 
+    parser.add_option("-L", "--ns-log", dest="ns_log",
+        help = "NS_LOG environmental variable to be set", 
+        default = "", type="str")
+
+    parser.add_option("-v", "--verbose",
+        help="Print debug output",
+        action="store_true", 
+        dest="verbose", default=False)
+
     (options, args) = parser.parse_args()
     
-    return options.socket_name
+    return options.socket_name, options.verbose, options.ns_log
+
+def run_server(socket_name, verbose = False, ns_log = None):
 
-def run_server(socket_name): 
-    ns3_wrapper = NS3Wrapper()
+    level = logging.DEBUG if verbose else logging.INFO
+
+    # Sets NS_LOG environmental variable for NS debugging
+    if ns_log:
+        os.environ["NS_LOG"] = ns_log
+
+    ###### ns-3 wrapper instantiation
+
+    ns3_wrapper = NS3Wrapper(loglevel=level)
 
     # create unix socket to receive instructions
     sock = create_socket(socket_name)
@@ -170,8 +209,6 @@ def run_server(socket_name):
         if not msg:
             # Ignore - connection lost
             break
-        ns3_wrapper.logger.debug("Message received %s args %s" % ( msg, str(args)))
 
         if msg == NS3WrapperMessage.SHUTDOWN:
            stop = True
@@ -185,7 +222,7 @@ def run_server(socket_name):
 
 if __name__ == '__main__':
             
-    socket_name = get_options()
+    (socket_name, verbose, ns_log) = get_options()
 
-    run_server(socket_name)
+    run_server(socket_name, verbose, ns_log)
 
index 064b32c..47525f9 100644 (file)
@@ -86,7 +86,7 @@ def load_ns3_module():
     return ns3mod
 
 class NS3Wrapper(object):
-    def __init__(self, homedir = None):
+    def __init__(self, homedir = None, loglevel = logging.INFO):
         super(NS3Wrapper, self).__init__()
         # Thread used to run the simulation
         self._simulation_thread = None
@@ -107,9 +107,8 @@ class NS3Wrapper(object):
             os.makedirs(home, 0755)
 
         # Logging
-        loglevel = os.environ.get("NS3LOGLEVEL", "debug")
         self._logger = logging.getLogger("ns3wrapper")
-        self._logger.setLevel(getattr(logging, loglevel.upper()))
+        self._logger.setLevel(loglevel)
         
         hdlr = logging.FileHandler(os.path.join(self.homedir, "ns3wrapper.log"))
         formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
@@ -180,7 +179,7 @@ class NS3Wrapper(object):
         return self._objects.get(uuid)
 
     def factory(self, type_name, **kwargs):
-        if type_name not in allowed_types:
+        if type_name not in self.allowed_types:
             msg = "Type %s not supported" % (type_name) 
             self.logger.error(msg)
  
index fd5e700..5cb7cc1 100644 (file)
@@ -159,7 +159,9 @@ def template_attributes(ns3, tid):
         attr_flags = "None"
         flags = attr_info.flags
         if (flags & ns3.TypeId.ATTR_SET) != ns3.TypeId.ATTR_SET:
-            attr_flags = "Flags.ExecReadOnly"
+            attr_flags = "Flags.Design"
+        elif (flags & ns3.TypeId.ATTR_CONSTRUCT) == ns3.TypeId.ATTR_CONSTRUCT:
+            attr_flags = "Flags.Construct"
 
         attr_name = attr_info.name
         checker = attr_info.checker
index bc4d0e7..8ef2b50 100644 (file)
@@ -52,11 +52,11 @@ class OMFApplication(OMFResource):
         env = Attribute("env", "Environnement variable of the application")
         stdin = Attribute("stdin", "Input of the application", default = "")
         sources = Attribute("sources", "Sources of the application", 
-                     flags = Flags.ExecReadOnly)
+                     flags = Flags.Design)
         sshuser = Attribute("sshUser", "user to connect with ssh", 
-                     flags = Flags.ExecReadOnly)
+                     flags = Flags.Design)
         sshkey = Attribute("sshKey", "key to use for ssh", 
-                     flags = Flags.ExecReadOnly)
+                     flags = Flags.Design)
         cls._register_attribute(appid)
         cls._register_attribute(path)
         cls._register_attribute(args)
index 9ce3e3b..7782bd8 100644 (file)
@@ -44,7 +44,7 @@ class PlanetlabNode(LinuxNode):
     @classmethod
     def _register_attributes(cls):
         ip = Attribute("ip", "PlanetLab host public IP address",
-                flags = Flags.ReadOnly)
+                    flags = Flags.Design)
 
         pl_url = Attribute("plcApiUrl", "URL of PlanetLab PLCAPI host \
                     (e.g. www.planet-lab.eu or www.planet-lab.org) ",
@@ -54,7 +54,7 @@ class PlanetlabNode(LinuxNode):
         pl_ptn = Attribute("plcApiPattern", "PLC API service regexp pattern \
                     (e.g. https://%(hostname)s:443/PLCAPI/ ) ",
                     default = "https://%(hostname)s:443/PLCAPI/",
-                    flags = Flags.ExecReadOnly)
+                    flags = Flags.Design)
     
         pl_user = Attribute("pluser", "PlanetLab account user, as the one to \
                     authenticate in the website) ",
index b3ce59d..f4b50c6 100644 (file)
@@ -43,13 +43,13 @@ class OVSWitch(LinuxApplication):
 
         """
         bridge_name = Attribute("bridge_name", "Name of the switch/bridge",
-                flags = Flags.ExecReadOnly)    
+                flags = Flags.Design)  
         virtual_ip_pref = Attribute("virtual_ip_pref", "Virtual IP/PREFIX of the switch",
-                flags = Flags.ExecReadOnly)       
+                flags = Flags.Design)  
         controller_ip = Attribute("controller_ip", "IP of the controller",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)  
         controller_port = Attribute("controller_port", "Port of the controller",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)  
 
         cls._register_attribute(bridge_name)
         cls._register_attribute(virtual_ip_pref)
index 57b6f16..cd2e848 100644 (file)
@@ -51,7 +51,7 @@ class OVSPort(LinuxApplication):
 
         """
         port_name = Attribute("port_name", "Name of the port",
-            flags = Flags.ExecReadOnly)                        
+            flags = Flags.Design)                      
 
         cls._register_attribute(port_name)
 
index a494212..359682c 100644 (file)
@@ -60,25 +60,25 @@ class OVSTunnel(LinuxApplication):
                 default = None,
                 allowed = ["PLAIN", "AES", "Blowfish", "DES", "DES3"],
                 type = Types.Enumerate, 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cipher_key = Attribute("cipherKey",
                 "Specify a symmetric encryption key with which to protect "
                 "packets across the tunnel. python-crypto must be installed "
                 "on the system." ,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         txqueuelen = Attribute("txQueueLen",
                 "Specifies the interface's transmission queue length. "
                 "Defaults to 1000. ", 
                 type = Types.Integer, 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         bwlimit = Attribute("bwLimit",
                 "Specifies the interface's emulated bandwidth in bytes "
                 "per second.",
                 type = Types.Integer, 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(cipher)
         cls._register_attribute(cipher_key)
index 5ca8590..6cc490a 100644 (file)
@@ -42,35 +42,35 @@ class PlanetlabTap(LinuxApplication):
     @classmethod
     def _register_attributes(cls):
         ip4 = Attribute("ip4", "IPv4 Address",
-              flags = Flags.ExecReadOnly)
+              flags = Flags.Design)
 
         mac = Attribute("mac", "MAC Address",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         prefix4 = Attribute("prefix4", "IPv4 network prefix",
                 type = Types.Integer,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         mtu = Attribute("mtu", "Maximum transmition unit for device",
                 type = Types.Integer)
 
         devname = Attribute("deviceName", 
                 "Name of the network interface (e.g. eth0, wlan0, etc)",
-                flags = Flags.ReadOnly)
+                flags = Flags.NoWrite)
 
         up = Attribute("up", "Link up", 
                 type = Types.Bool)
         
         snat = Attribute("snat", "Set SNAT=1", 
                 type = Types.Bool,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         
         pointopoint = Attribute("pointopoint", "Peer IP address", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         tear_down = Attribute("tearDown", "Bash script to be executed before " + \
                 "releasing the resource",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(ip4)
         cls._register_attribute(mac)
index e09d490..cd11bfa 100644 (file)
@@ -41,13 +41,13 @@ def lexec(command,
         command = "su %s ; %s " % (user, command)
 
 
-    p = subprocess.Popen(command, shell=True, 
+    proc = subprocess.Popen(command, shell=True, 
             stdout = subprocess.PIPE, 
             stderr = subprocess.PIPE)
             #stdin  = stdin)
 
-    out, err = p.communicate()
-    return (out, err)
+    out, err = proc.communicate()
+    return ((out, err), proc)
 
 def lcopy(source, dest, recursive = False):
     """
@@ -64,7 +64,7 @@ def lcopy(source, dest, recursive = False):
     command.append(src)
     command.append(dst)
     
-    p = subprocess.Popen(command, 
+    proc = subprocess.Popen(command, 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE)
 
@@ -128,12 +128,12 @@ def lspawn(command, pidfile,
             'create' : 'mkdir -p %s ; ' % (shell_escape(home),) if create_home else '',
         }
 
-    (out,err),proc = lexec(cmd)
+    (out,err), proc = lexec(cmd)
     
     if proc.wait():
         raise RuntimeError, "Failed to set up application on host %s: %s %s" % (host, out,err,)
 
-    return (out,err),proc
+    return ((out,err), proc)
 
 def lgetpid(pidfile):
     """
@@ -148,7 +148,7 @@ def lgetpid(pidfile):
         or None if the pidfile isn't valid yet (maybe the process is still starting).
     """
 
-    (out,err),proc = lexec("cat %s" % pidfile )
+    (out,err), proc = lexec("cat %s" % pidfile )
         
     if proc.wait():
         return None
@@ -172,7 +172,7 @@ def lstatus(pid, ppid):
         One of NOT_STARTED, RUNNING, FINISHED
     """
 
-    (out,err),proc = lexec(
+    (out,err), proc = lexec(
         # Check only by pid. pid+ppid does not always work (especially with sudo) 
         " (( ps --pid %(pid)d -o pid | grep -c %(pid)d && echo 'wait')  || echo 'done' ) | tail -n 1" % {
             'ppid' : ppid,
@@ -187,8 +187,8 @@ def lstatus(pid, ppid):
         status = (out.strip() == 'wait')
     else:
         return ProcStatus.NOT_STARTED
+
     return ProcStatus.RUNNING if status else ProcStatus.FINISHED
 
 def lkill(pid, ppid, sudo = False):
     """
index 404fc5d..aea015b 100644 (file)
@@ -41,6 +41,8 @@ import unittest
 class LinuxNS3ClientTest(unittest.TestCase):
     def setUp(self):
         self.socket_name = os.path.join("/", "tmp", "NS3WrapperServer.sock")
+        if os.path.exists(self.socket_name):
+            os.remove(self.socket_name) 
 
     def tearDown(self):
         os.remove(self.socket_name) 
diff --git a/test/resources/linux/ns3/ns3simulator.py b/test/resources/linux/ns3/ns3simulator.py
new file mode 100644 (file)
index 0000000..9f17072
--- /dev/null
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+#
+#    NEPI, a framework to manage network experiments
+#    Copyright (C) 2013 INRIA
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+
+#
+# Network topology
+#
+#       n0    n1   n2   n3
+#       |     |    |    |
+#       -----------------
+#
+#  node n0 sends IGMP traffic to node n3
+
+
+from nepi.execution.ec import ExperimentController 
+from nepi.resources.ns3.ns3server import run_server
+
+import os
+import threading
+import time
+import unittest
+
+class LinuxNS3ClientTest(unittest.TestCase):
+    def setUp(self):
+        self.socket_name = os.path.join("/", "tmp", "NS3WrapperServerSimu.sock")
+        if os.path.exists(self.socket_name):
+            os.remove(self.socket_name) 
+
+    def tearDown(self):
+        os.remove(self.socket_name) 
+
+    def test_runtime_attr_modify(self):
+        thread = threading.Thread(target = run_server,
+                args = [self.socket_name], 
+                kwargs = {"verbose" : True,
+                    "ns_log": "V4Ping:Node"})
+
+        thread.setDaemon(True)
+        thread.start()
+
+        time.sleep(1)
+
+        ec = ExperimentController(exp_id = "test-ns3-simu")
+        
+        node = ec.register_resource("LinuxNode")
+        ec.set(node, "hostname", "localhost")
+
+        simu = ec.register_resource("LinuxNS3Simulator")
+        ec.set(simu, "socketName", self.socket_name)
+        ec.register_connection(simu, node)
+
+        nsnode1 = ec.register_resource("ns3::Node")
+        ec.register_connection(nsnode1, simu)
+
+        ipv41 = ec.register_resource("ns3::Ipv4L3Protocol")
+        ec.register_connection(nsnode1, ipv41)
+
+        arp1 = ec.register_resource("ns3::ArpL3Protocol")
+        ec.register_connection(nsnode1, arp1)
+        
+        icmp1 = ec.register_resource("ns3::Icmpv4L4Protocol")
+        ec.register_connection(nsnode1, icmp1)
+
+        p1 = ec.register_resource("ns3::PointToPointNetDevice")
+        ec.set(p1, "ip", "10.0.0.1")
+        ec.set(p1, "prefix", "30")
+        ec.register_connection(nsnode1, p1)
+        q1 = ec.register_resource("ns3::DropTailQueue")
+        ec.register_connection(nsnode1, q1)
+
+        nsnode2 = ec.register_resource("ns3::Node")
+        ec.register_connection(nsnode2, simu)
+
+        ipv42 = ec.register_resource("ns3::Ipv4L3Protocol")
+        ec.register_connection(nsnode2, ipv42)
+
+        arp2 = ec.register_resource("ns3::ArpL3Protocol")
+        ec.register_connection(nsnode2, arp2)
+        
+        icmp2 = ec.register_resource("ns3::Icmpv4L4Protocol")
+        ec.register_connection(nsnode2, icmp2)
+
+        p2 = ec.register_resource("ns3::PointToPointNetDevice")
+        ec.set(p2, "ip", "10.0.0.2")
+        ec.set(p2, "prefix", "30")
+        ec.register_connection(nsnode2, p2)
+        q2 = ec.register_resource("ns3::DropTailQueue")
+        ec.register_connection(nsnode2, q2)
+
+        # Create channel
+        chan = ec.register_resource("ns3::PointToPointChannel")
+        ec.set(chan, "Delay", "0s")
+        ec.register_connection(chan, p1)
+        ec.register_connection(chan, p2)
+
+        ### create pinger
+        ping = ec.register_resource("ns3::V4Ping")
+        ec.set (ping, "Remote", "10.0.0.2")
+        ec.set (ping, "Interval", "1s")
+        ec.set (ping, "Verbose", True)
+        ec.set (ping, "StartTime", "0s")
+        ec.set (ping, "StopTime", "20s")
+        ec.register_connection(ping, nsnode1)
+
+        ec.deploy()
+
+        time.sleep(5)
+
+        ec.shutdown()
+
+if __name__ == '__main__':
+    unittest.main()
+