from nepi.util.constants import TIME_NOW
import os
import time
+import resourcealloc
class TestbedController(testbed_impl.TestbedController):
def __init__(self, testbed_version):
super(TestbedController, self).do_preconfigure()
def do_resource_discovery(self):
- # Do what?
-
- # Provisional algo:
+ to_provision = self._to_provision = set()
+
+ # Initial algo:
# look for perfectly defined nodes
# (ie: those with only one candidate)
- to_provision = self._to_provision = set()
for guid, node in self._elements.iteritems():
if isinstance(node, self._node.Node) and node._node_id is None:
# Try existing nodes first
# Try again including unassigned nodes
candidates = node.find_candidates()
if len(candidates) > 1:
- raise RuntimeError, "Cannot assign resources for node %s, too many candidates" % (guid,)
+ continue
if len(candidates) == 1:
node_id = iter(candidates).next()
node.assign_node_id(node_id)
to_provision.add(node_id)
elif not candidates:
raise RuntimeError, "Cannot assign resources for node %s, no candidates" % (guid,)
+
+ # Now do the backtracking search for a suitable solution
+ # First with existing slice nodes
+ reqs = []
+ nodes = []
+ for guid, node in self._elements.iteritems():
+ if isinstance(node, self._node.Node) and node._node_id is None:
+ # Try existing nodes first
+ # If we have only one candidate, simply use it
+ candidates = node.find_candidates(
+ filter_slice_id = self.slice_id)
+ reqs.append(candidates)
+ nodes.append(node)
+
+ if nodes and reqs:
+ try:
+ solution = resourcealloc.alloc(reqs)
+ except resourcealloc.ResourceAllocationError:
+ # Failed, try again with all nodes
+ reqs = []
+ for node in nodes:
+ candidates = node.find_candidates()
+ reqs.append(candidates)
+
+ solution = resourcealloc.alloc(reqs)
+ to_provision.update(solution)
+
+ # Do assign nodes
+ for node, node_id in zip(nodes, solution):
+ node.assign_node_id(node_id)
def do_provisioning(self):
if self._to_provision:
# asserts at the end, to make sure there's proper cleanup
self.assertEqual(ping_result, "")
+
+ @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+ def test_discovery(self):
+ instance = self.make_instance()
+
+ instance.defer_create(2, "Node")
+ instance.defer_create_set(2, "operatingSystem", "f12")
+ instance.defer_create(3, "Node")
+ instance.defer_create_set(3, "operatingSystem", "f12")
+ instance.defer_create(4, "NodeInterface")
+ instance.defer_connect(2, "devs", 4, "node")
+ instance.defer_create(5, "NodeInterface")
+ instance.defer_connect(3, "devs", 5, "node")
+ instance.defer_create(6, "Internet")
+ instance.defer_connect(4, "inet", 6, "devs")
+ instance.defer_connect(5, "inet", 6, "devs")
+ instance.defer_create(7, "Application")
+ instance.defer_create_set(7, "command", "ping -qc1 {#[GUID-5].addr[0].[Address]#}")
+ instance.defer_add_trace(7, "stdout")
+ instance.defer_add_trace(7, "stderr")
+ instance.defer_connect(7, "node", 2, "apps")
+
+ comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data.
+
+--- .* ping statistics ---
+1 packets transmitted, 1 received, 0% packet loss, time \d*ms.*
+"""
+
+ try:
+ instance.do_setup()
+ instance.do_create()
+ instance.do_connect_init()
+ instance.do_connect_compl()
+ instance.do_preconfigure()
+
+ # Manually replace netref
+ instance.set(7, "command",
+ instance.get(7, "command")
+ .replace("{#[GUID-5].addr[0].[Address]#}",
+ instance.get_address(5, 0, "Address") )
+ )
+
+ instance.do_configure()
+
+ instance.do_prestart()
+ instance.start()
+ while instance.status(7) != STATUS_FINISHED:
+ time.sleep(0.5)
+ ping_result = instance.trace(7, "stdout") or ""
+ instance.stop()
+ finally:
+ instance.shutdown()
+
+ # asserts at the end, to make sure there's proper cleanup
+ self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE),
+ "Unexpected trace:\n" + ping_result)
+
if __name__ == '__main__':