from constants import TESTBED_ID
import plcapi
import operator
+import os
+
+from nepi.util.constants import STATUS_NOT_STARTED, STATUS_RUNNING, \
+ STATUS_FINISHED
class Application(object):
def __init__(self, api=None):
# Those are filled when an actual node is connected
self.node = None
+
+ # Those are filled when the app is started
+ # Having both pid and ppid makes it harder
+ # for pid rollover to induce tracking mistakes
+ self._pid = None
+ self._ppid = None
+ self._stdout_path = None
+ self._stderr_path = None
def __str__(self):
return "%s<command:%s%s>" % (
def validate(self):
pass
+ def start(self):
+ pass
+
+ def status(self):
+ return STATUS_FINISHED
+
+ def kill(self):
+ status = self.status()
+ if status == STATUS_RUNNING:
+ # TODO: kill by pid & ppid
+ pass
+
+ def remote_trace_path(self, whichtrace):
+ if whichtrace == 'stdout':
+ tracefile = self._stdout_path
+ elif whichtrace == 'stderr':
+ tracefile = self._stderr_path
+ else:
+ tracefile = None
+
+ return tracefile
+
+ def sync_trace(self, local_dir, whichtrace):
+ tracefile = self.remote_trace_path(whichtrace)
+ if not tracefile:
+ return None
+
+ local_path = os.join(local_dir, tracefile)
+
+ # TODO: sync files
+ f = open(local_path, "w")
+ f.write("BLURP!")
+ f.close()
+
+ return local_path
+
+
for element in self._elements.values():
element.destroy()
- def trace_filename(self, guid, trace_id):
- # TODO: Need to be defined inside a home!!!! with and experiment id_code
- return os.path.join(self.home_directory, "%d_%s" % (guid, trace_id))
-
+ def trace(self, guid, trace_id, attribute='value'):
+ app = self._elements[guid]
+
+ if attribute == 'value':
+ path = app.sync_trace(self.home_directory, trace_id)
+ if path:
+ fd = open(path, "r")
+ content = fd.read()
+ fd.close()
+ else:
+ content = None
+ elif attribute == 'path':
+ content = app.remote_trace_path(trace_id)
+ else:
+ content = None
+ return content
+
def follow_trace(self, trace_id, trace):
self._traces[trace_id] = trace
traces = testbed_instance._get_traces(guid)
app = testbed_instance.elements[guid]
- app.stdout = testbed_instance.trace_filename(guid, "stdout")
- app.stderr = testbed_instance.trace_filename(guid, "stderr")
+ app.stdout = "stdout" in traces
+ app.stderr = "stderr" in traces
- # TODO
- pass
+ app.start()
+
+def stop_application(testbed_instance, guid):
+ app = testbed_instance.elements[guid]
+ app.stop()
### Status functions ###
def status_application(testbed_instance, guid):
if guid not in testbed_instance.elements.keys():
return STATUS_NOT_STARTED
+
app = testbed_instance.elements[guid]
- # TODO
- return STATUS_FINISHED
+ return app.status()
### Configure functions ###
addresses = testbed_instance._add_address[guid]
for address in addresses:
(address, netprefix, broadcast) = address
- # TODO
+ raise NotImplementedError, "C'mon... TUNs are hard..."
# Do some validations
element.validate()
"create_function": create_application,
"start_function": start_application,
"status_function": status_application,
+ "stop_function": stop_application,
"box_attributes": ["command", "sudo"],
"connector_types": ["node"],
"traces": ["stdout", "stderr"]
instance.start()
while instance.status(7) != STATUS_FINISHED:
time.sleep(0.5)
- ping_result = instance.trace(7, "stdout")
- comp_result = r"""PING .* \(.*) \d*\(\d*\) bytes of data.
+ ping_result = instance.trace(7, "stdout") or ""
+ comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data.
--- .* ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time \d*ms.*
"""
- self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE))
+ self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE),
+ "Unexpected trace:\n" + ping_result)
instance.stop()
instance.shutdown()