|
9 | 9 |
|
10 | 10 | import click |
11 | 11 | import yaml |
| 12 | +from pyparsing import alphanums |
| 13 | +from pyparsing import Group |
| 14 | +from pyparsing import OneOrMore |
| 15 | +from pyparsing import ParseException |
| 16 | +from pyparsing import Suppress |
| 17 | +from pyparsing import Word |
12 | 18 |
|
13 | 19 |
|
14 | 20 | DEBUG = False |
15 | 21 |
|
16 | 22 |
|
| 23 | +class Conn: |
| 24 | + def __init__(self, a, b): |
| 25 | + self.a = a |
| 26 | + self.b = b |
| 27 | + |
| 28 | + def __eq__(self, other): |
| 29 | + if self.a == other.a and self.b == other.b or self.a == other.b and self.b == other.a: |
| 30 | + return True |
| 31 | + return False |
| 32 | + |
| 33 | + def __hash__(self): |
| 34 | + enps = [self.a, self.b] |
| 35 | + sorted_enps = sorted(enps) |
| 36 | + return hash(tuple(sorted_enps)) |
| 37 | + |
| 38 | + def __repr__(self): |
| 39 | + return f"{self.a} -- {self.b}" |
| 40 | + |
| 41 | + |
17 | 42 | def random_port(tcp=True): |
18 | 43 | """Get a random port number for making a socket |
19 | 44 |
|
@@ -268,5 +293,43 @@ def ping(filename, count, validate): |
268 | 293 | sys.exit(127) |
269 | 294 |
|
270 | 295 |
|
| 296 | +def read_and_parse_dot(filename): |
| 297 | + group = Group(Word(alphanums) + Suppress("--") + Word(alphanums)) + Suppress(";") |
| 298 | + dot = Suppress("graph {") + OneOrMore(group) + Suppress("}") |
| 299 | + |
| 300 | + with open(filename) as f: |
| 301 | + raw_data = f.read() |
| 302 | + data = dot.parseString(raw_data).asList() |
| 303 | + return {Conn(c[0], c[1]) for c in data} |
| 304 | + |
| 305 | + |
| 306 | +@main.command("dot-compare") |
| 307 | +@click.option("--wait", default=None) |
| 308 | +@click.argument("filename_one") |
| 309 | +@click.argument("filename_two") |
| 310 | +def dot_compare(filename_one, filename_two, wait): |
| 311 | + |
| 312 | + if wait: |
| 313 | + start = time.time() |
| 314 | + while True: |
| 315 | + try: |
| 316 | + assert read_and_parse_dot(filename_one) == read_and_parse_dot(filename_two) |
| 317 | + sys.stderr.write("Matched\n") |
| 318 | + sys.exit(0) |
| 319 | + except (AssertionError, ParseException, FileNotFoundError) as e: |
| 320 | + if time.time() < start + float(wait): |
| 321 | + time.sleep(1) |
| 322 | + else: |
| 323 | + sys.stderr.write("Failed match\n") |
| 324 | + raise e |
| 325 | + else: |
| 326 | + try: |
| 327 | + assert read_and_parse_dot(filename_one) == read_and_parse_dot(filename_two) |
| 328 | + sys.stderr.write("Matched\n") |
| 329 | + except AssertionError: |
| 330 | + sys.stderr.write("Failed match\n") |
| 331 | + sys.exit(127) |
| 332 | + |
| 333 | + |
271 | 334 | if __name__ == "__main__": |
272 | 335 | main() |
0 commit comments