diff options
author | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2017-05-11 13:15:10 +0000 |
---|---|---|
committer | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2017-05-11 13:15:10 +0000 |
commit | bb0fb67c1fc525e0b9aa17b5e39d385c8601dfae (patch) | |
tree | fb4936363884896463aa446ac5baa5f79a7e1061 | |
parent | bf9a98603c8fc8dd8f15a7d54ffb2111fc6428a9 (diff) | |
parent | 10da73cd31a26ad2b4a95bb1ec3d02f6afc57dc6 (diff) | |
download | rumba-bb0fb67c1fc525e0b9aa17b5e39d385c8601dfae.tar.gz rumba-bb0fb67c1fc525e0b9aa17b5e39d385c8601dfae.zip |
Merge branch 'sander' into 'master'
StoryBoard API proposal
See merge request !45
-rwxr-xr-x | examples/example.py | 20 | ||||
-rw-r--r-- | rumba/model.py | 127 |
2 files changed, 136 insertions, 11 deletions
diff --git a/examples/example.py b/examples/example.py index 56193c2..1acc883 100755 --- a/examples/example.py +++ b/examples/example.py @@ -17,7 +17,6 @@ import rumba.prototypes.irati as irati import rumba.log as log - log.set_logging_level('DEBUG') n1 = NormalDIF("n1", policies = {"rmt.pff": "lfa", @@ -27,19 +26,16 @@ e1 = ShimEthDIF("e1") a = Node("a", difs = [n1, e1], - dif_registrations = {n1 : [e1]}, - registrations = {"a.crap" : [n1]}, - bindings = {"a.crap" : "/usr/bin/crap"}) + dif_registrations = {n1 : [e1]}) b = Node("b", difs = [e1, n1], - dif_registrations = {n1 : [e1]}) + dif_registrations = {n1 : [e1]}, + client = True) -tb = qemu.Testbed(exp_name = "example1", - username = "root", - password = "root", - bzimage = '/home/vmaffione/git/rlite/demo/buildroot/bzImage', - initramfs = '/home/vmaffione/git/rlite/demo/buildroot/rootfs.cpio') +tb = jfed.Testbed(exp_name = "example1", + username = "user1", + cert_file = "/home/user1/cert.pem") exp = rl.Experiment(tb, nodes = [a, b]) @@ -48,5 +44,9 @@ print(exp) try: exp.swap_in() exp.bootstrap_prototype() + c1 = Client("rinaperf", options ="-t perf -s 1000 -c 10000") + s1 = Server("rinaperf", arrival_rate=2, mean_duration=5, options = "-l", nodes = [a], clients = [c1]) + sb = StoryBoard(exp, 3600, servers = [s1]) + sb.start() finally: exp.swap_out() diff --git a/rumba/model.py b/rumba/model.py index 0b9fc7a..285d937 100644 --- a/rumba/model.py +++ b/rumba/model.py @@ -20,6 +20,9 @@ # MA 02110-1301 USA import abc +import random + +import time import rumba.log as log @@ -152,7 +155,7 @@ class SSHConfig: # class Node: def __init__(self, name, difs=None, dif_registrations=None, - registrations=None, bindings=None): + registrations=None, bindings=None, client=False): self.name = name if difs is None: difs = list() @@ -170,6 +173,7 @@ class Node: self.bindings = bindings self.ssh_config = SSHConfig(name) self.ipcps = [] + self.client = client self._validate() @@ -564,3 +568,124 @@ class Experiment: def swap_out(self): # Undo the testbed (testbed-specific) self.testbed.swap_out(self) + + +# Base class for client programs +# +# @ap: Application Process binary +# @options: Options to pass to the binary +# +class Client(object): + def __init__(self, ap, options=None): + self.ap = ap + self.options = options + + def start_process(self, node, duration, start_time): + return ClientProcess(self.ap, node, duration, start_time, self.options) + + +# Base class for client processes +# +# @ap: Application Process binary +# @node: The node on which this process should run +# @duration: The time (in seconds) this process should run +# @start_time: The time at which this process is started. +# @options: Options to pass to the binary +# +class ClientProcess(Client): + def __init__(self, ap, node, duration, start_time, options=None): + super(ClientProcess, self).__init__(ap, options=options) + self.node = node + self.duration = duration + self.start_time = start_time + self.run() + self.running = True + + def run(self): + pass # TODO to be implemented + + def stop(self): + pass # TODO to be implemented + + def check(self, now): + if not self.running: + return + if now - self.start_time >= self.duration: + self.stop() + + +# Base class for server programs +# +# @ap: Application Process binary +# @arrival_rate: Average requests/s to be received by this server +# @mean_duration: Average duration of a client connection (in seconds) +# @options: Options to pass to the binary +# @max_clients: Maximum number of clients to serve +# @clients: Client binaries that will use this server +# @nodes: Specific nodes to start this server on +# +class Server: + def __init__(self, ap, arrival_rate, mean_duration, + options=None, max_clients=None, + clients=None, nodes=None): + self.ap = ap + self.options = options + self.max_clients = max_clients + if clients is None: + clients = list() + self.clients = clients + self.nodes = nodes + self.arrival_rate = arrival_rate # mean requests/s + self.mean_duration = mean_duration # in seconds + + def add_client(self, client): + self.clients.append(client) + + def del_client(self, client): + self.clients.remove(client) + + def add_node(self, node): + self.nodes.append(node) + + def del_node(self, node): + self.nodes.remove(node) + + def get_new_clients(self, interval): + """ + Returns a list of clients of size appropriate to the server's rate. + + The list's size should be a sample from Poisson(arrival_rate) over + interval seconds. + Hence, the average size should be interval * arrival_rate. + """ + pass + + def make_client_process(self): + """Returns a client of this server""" + if len(self.clients) == 0: + raise Exception("Server %s has empty client list," % (self,)) + pass # TODO should return a ClientProcess + + +# Base class for ARCFIRE storyboards +# +# @experiment: Experiment to use as input +# @duration: Duration of the whole storyboard +# @servers: App servers available in the network +# +class StoryBoard: + def __init__(self, experiment, duration, servers=None): + self.experiment = experiment + self.duration = duration + if servers is None: + servers = list() + self.servers = servers + + def add_server(self, server): + self.servers.append(server) + + def del_server(self, server): + self.servers.remove(server) + + def start(self): + pass |