Ticket #21: emulation support - vsys requirement checking when attaching a TunInterfa...
authorClaudio-Daniel Freire <claudio-daniel.freire@inria.fr>
Tue, 26 Apr 2011 13:29:13 +0000 (15:29 +0200)
committerClaudio-Daniel Freire <claudio-daniel.freire@inria.fr>
Tue, 26 Apr 2011 13:29:13 +0000 (15:29 +0200)
src/nepi/testbeds/planetlab/node.py
test/testbeds/planetlab/execute.py

index 10ff593..a13f574 100644 (file)
@@ -7,6 +7,7 @@ import operator
 import rspawn
 import time
 import os
+import collections
 
 from nepi.util import server
 
@@ -52,8 +53,9 @@ class Node(object):
         self.max_num_external_ifaces = None
         self.timeframe = 'm'
         
-        # Applications add requirements to connected nodes
+        # Applications and routes add requirements to connected nodes
         self.required_packages = set()
+        self.required_vsys = set()
         
         # Testbed-derived attributes
         self.slicename = None
@@ -111,6 +113,31 @@ class Node(object):
                 candidates &= set(map(operator.itemgetter('node_id'),
                     self._api.GetNodeTags(filters=tagfilter, fields=fields)))
         
+        # filter by vsys tags - special case since it doesn't follow
+        # the usual semantics
+        if self.required_vsys:
+            newcandidates = collections.defaultdict(set)
+            
+            vsys_tags = self._api.GetNodeTags(
+                tagname='vsys', 
+                node_id = list(candidates), 
+                fields = ['node_id','value'])
+            
+            vsys_tags = map(
+                operator.itemgetter(['node_id','value']),
+                vsys_tags)
+            
+            required_vsys = self.required_vsys
+            for node_id, value in vsys_tags:
+                if value in required_vsys:
+                    newcandidates[value].add(node_id)
+            
+            # take only those that have all the required vsys tags
+            newcandidates = reduce(
+                lambda accum, new : accum & new,
+                newcandidates.itervalues(),
+                candidates)
+        
         # filter by iface count
         if self.min_num_external_ifaces is not None or self.max_num_external_ifaces is not None:
             # fetch interfaces for all, in one go
index f20c127..758959e 100755 (executable)
@@ -161,6 +161,45 @@ FIONREAD = 0x[0-9a-fA-F]{8}.*
         instance.stop()
         instance.shutdown()
         
+    @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+    def test_simple_vsys(self):
+        instance = self.make_instance()
+        
+        instance.defer_create(2, "Node")
+        instance.defer_create_set(2, "hostname", "onelab11.pl.sophia.inria.fr")
+        instance.defer_create(3, "NodeInterface")
+        instance.defer_connect(2, "devs", 3, "node")
+        instance.defer_create(4, "Internet")
+        instance.defer_connect(3, "inet", 4, "devs")
+        instance.defer_create(5, "TunInterface")
+        instance.defer_connect(2, "devs", 5, "node")
+        instance.defer_create(6, "Application")
+        instance.defer_create_set(6, "command", """
+set -e
+test -e /vsys/vif_up.in
+test -e /vsys/vif_up.out
+test -e /vsys/fd_tuntap.control
+echo 'OKIDOKI'
+""")
+        instance.defer_create_set(6, "sudo", True) # only sudo has access to /vsys
+        instance.defer_add_trace(6, "stdout")
+        instance.defer_connect(6, "node", 2, "apps")
+
+        instance.do_setup()
+        instance.do_create()
+        instance.do_connect()
+        instance.do_preconfigure()
+        instance.do_configure()
+        
+        instance.start()
+        while instance.status(6) != STATUS_FINISHED:
+            time.sleep(0.5)
+        test_result = (instance.trace(6, "stdout") or "").strip()
+        comp_result = "OKIDOKI"
+        self.assertEqual(comp_result, test_result)
+        instance.stop()
+        instance.shutdown()
+        
 
 if __name__ == '__main__':
     unittest.main()