diff --git a/esds/helpers/platform.py b/esds/helpers/platform.py index eee2139..cc08709 100644 --- a/esds/helpers/platform.py +++ b/esds/helpers/platform.py @@ -1,10 +1,137 @@ -import yaml +import yaml, os class YAMLPlatformFile: def __init__(self, file_path): self.file_path=file_path + self.default={ + "breakpoints": [], + "breakpoints_every": None, + "debug": False, + "interferences": True, + "node_count": 0, + "implementations": [], + "interfaces": dict() + } + with open(file_path) as f: self.platform = yaml.load(f, Loader=yaml.FullLoader) - print(self.platform) \ No newline at end of file + + ##### General + if "general" in self.platform: + self.parse_general() + ##### Nodes + if "nodes" in self.platform: + self.parse_nodes() + else: + self.parse_error("platform file has no nodes section") + ##### Interfaces + if "interfaces" in self.platform: + self.parse_interfaces() + else: + self.parse_error("platform file has no interfaces section") + + def parse_error(self,msg): + raise Exception("Fail to parse platform file \""+self.file_path+"\": "+msg) + + def parse_link_range(self,r): + elt=r.split("-") + if len(elt) == 2: + return(range(int(elt[0]),int(elt[1]))) + else: + return([int(elt[0])]) + + def parse_link_bw(self,bw): + for i,c in enumerate(bw): + if not c.isdigit() and c != ".": + break + number=float(bw[:i]) + unit=bw[i:] + number=number*1000 if unit == "Mbps" else number + number=number*1000*8 if unit == "MBps" else number + number=number*100 if unit == "kbps" else number + number=number*100*8 if unit == "kBps" else number + number=number*8 if unit == "Bps" else number + return(number) + + def parse_link_lat(self,lat): + for i,c in enumerate(lat): + if not c.isdigit() and c != ".": + break + number=float(lat[:i]) + unit=lat[i:] + number=number*60 if unit in ["m","M"] else number + number=number*3600 if unit in ["h","H"] else number + number=number/1000 if unit in ["ms","MS"] else number + return(number) + + def parse_link(self,link): + words=link.split() + if len(words) == 4: + return(( + self.parse_link_range(words[0]), + self.parse_link_bw(words[1]), + self.parse_link_lat(words[2]), + self.parse_link_range(words[3]))) + elif len(words) == 2: + return(( + range(0,self.default["node_count"]), + self.parse_link_bw(words[0]), + self.parse_link_lat(words[1]), + range(0,self.default["node_count"]))) + return(None) + + def parse_interfaces(self): + interfaces=self.platform["interfaces"] + for i in interfaces: + is_wired=interfaces[i]["wireless"] + links=list() + if type(interfaces[i]["links"]) == list: + for link in interfaces[i]["links"]: + links.append(self.parse_link(link)) + else: + links.append(self.parse_link(interfaces[i]["links"])) + ##### Create network matrix + for link in links: + print(link) + + def parse_nodes(self): + nodes=self.platform["nodes"] + if "count" in nodes: + if not str(nodes["count"]).isnumeric(): + self.parse_error("node count should be a number") + self.default["node_count"]=nodes["count"] + if "implementations" in nodes: + if type(nodes["implementations"]) != list: + self.parse_error("nodes implementations should be a list of file path") + for file in nodes["implementations"]: + if not os.path.exists(file): + self.parse_error("File "+file+ " not found") + path, extension = os.path.splitext(file) + if extension != ".py": + self.parse_error("File "+file+" must be a python file") + self.default["implementations"].append(path) + count = len(nodes["implementations"]) + if count > 1 and count != self.default["node_count"]: + self.parse_error("If more than one implementation is specified, each node implementation should be provided ("+str(self.default["node_count"])+" in total)") + + + def parse_general(self): + general=self.platform["general"] + if "breakpoints" in general: + if type(general["breakpoints"]) != list: + self.parse_error("breakpoints should be a list of number") + self.default["breakpoints"]=general["breakpoints"] + if "breakpoints_every" in general: + if not str(general["breakpoints_every"]).isnumeric(): + self.parse_error("breakpoints_every should be a number") + self.default["breakpoints_every"]=general["breakpoints_every"] + if "debug" in general: + if type(general["debug"]) != bool: + self.parse_error("debug should be on or off") + self.default["debug"]=general["debug"] + if "interferences" in general: + if type(general["interferences"]) != bool: + self.parse_error("interferences should be on or off") + self.default["interferences"]=general["interferences"] diff --git a/example/platform.yaml b/example/platform.yaml index b8aa794..f29ebd2 100644 --- a/example/platform.yaml +++ b/example/platform.yaml @@ -7,13 +7,13 @@ general: nodes: count: 5 implementations: - - file.py + - sender.py interfaces: wlan0: wireless: yes links: - - 0: 5-8 => 10MBps + - 0 1Bps 10s 0 eth0: wireless: no - links: 5Mbps \ No newline at end of file + links: 5Mbps 10s \ No newline at end of file