-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimulate
executable file
·123 lines (106 loc) · 5.3 KB
/
simulate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/python3
import json
import argparse
import sys
from datetime import datetime
from simulio.graph import UnidirectionalRing, BidirectionalRing, KRegularRing, CompleteGraph, BipartiteGraph, \
StarGraph, BinaryGraph, RandomGraph, ArbitraryGraph
from simulio.simulator import SyncSimulator, SyncSimulatorWithRandomUID, AsyncSimulator, AsyncSimulatorWithRandomUID, \
OrderedAsyncSimulator, OrderedAsyncSimulatorWithRandomUID
from simulio.transition import parse
UNIDIRECTIONAL_RING = 'unidirectional-ring'
BIDIRECTIONAL_RING = 'bidirectional-ring'
K_REGULAR_RING = 'k-regular-ring'
COMPLETE_GRAPH = 'complete'
BIPARTITE_GRAPH = 'bipartite'
STAR_GRAPH = 'star'
BINARY_GRAPH = 'binary'
RANDOM_GRAPH = 'random'
ARBITRARY_GRAPH = 'arbitrary'
SYNC = "sync"
ASYNC = "async"
ORDERED_ASYNC = "ordered-async"
DEFAULT_LIMIT = 10000
def run_cli():
start_time = datetime.now()
parser = argparse.ArgumentParser(description='Simulate I/O automata on given Graph')
parser.add_argument('-a', '--automata', required=True,
help='Automata algorithm file')
parser.add_argument('-g', '--graph', required=True, nargs='+',
metavar=('unidirectional-ring, bidirectional-ring, k-regular-ring(N,K), complete,'
' bipartite(N,M), star, binary, random(N nodes M edges), arbitrary'
'SIZE, N M, GRAPH_FILE'),
help='Simulate the automaton operating on GRAPH')
parser.add_argument('-t', '--type',
choices=[SYNC, ASYNC, ORDERED_ASYNC],
help='type of simulator(sync, async, ordered-async)')
parser.add_argument('-r', '--random-ids', action='store_true',
help="Generate random uids for graph nodes")
parser.add_argument('-o', '--output', type=argparse.FileType('w'), default='-',
help='Output file to write result to it')
parser.add_argument('-b', '--byzantine', nargs='+', metavar='AUTOMATA',
help="Automata algorithms for byzantine nodes")
parser.add_argument('--link-failure', metavar='PROBABILITY', default=0, type=float,
help="Probability of message lost on every link. Float number between 0 and 1."
" Under link-failure the default limit steps is " + str(DEFAULT_LIMIT))
parser.add_argument('-l', '--limit', type=int,
help="Run simulator for LIMIT steps. Under link-failure the default limit is "
+ str(DEFAULT_LIMIT) + " steps")
parser.add_argument('-s', '--sleep', type=float, default=0.0,
help='Sleep for this number of seconds between steps') # TODO
args = parser.parse_args()
with open(str(args.automata)) as f:
automata = parse(f.readlines())
byzantine_automatons = []
if args.byzantine is not None:
for file in args.byzantine:
with open(str(file)) as f:
byzantine_automatons.append(parse(f.readlines()))
graph_type = args.graph[0]
if graph_type == UNIDIRECTIONAL_RING:
graph = UnidirectionalRing(int(args.graph[1]))
elif graph_type == BIDIRECTIONAL_RING:
graph = BidirectionalRing(int(args.graph[1]))
elif graph_type == COMPLETE_GRAPH:
graph = CompleteGraph(int(args.graph[1]))
elif graph_type == BIPARTITE_GRAPH:
graph = BipartiteGraph(int(args.graph[1]), int(args.graph[2]))
elif graph_type == STAR_GRAPH:
graph = StarGraph(int(args.graph[1]))
elif graph_type == RANDOM_GRAPH:
graph = RandomGraph(int(args.graph[1]), int(args.graph[2]))
elif graph_type == K_REGULAR_RING:
graph = KRegularRing(int(args.graph[1]), int(args.graph[2]))
elif graph_type == BINARY_GRAPH:
graph = BinaryGraph(int(args.graph[1]))
else: # ARBITRARY_GRAPH
graph = ArbitraryGraph(str(args.graph[1]))
limit = args.limit
if args.link_failure != 0 and args.limit is None: # TODO node failure
limit = DEFAULT_LIMIT
link_failure_prob = float(args.link_failure)
simulator = None
if args.type == SYNC:
if args.random_ids:
simulator = SyncSimulatorWithRandomUID(graph, automata, byzantine_automatons, limit, link_failure_prob)
else:
simulator = SyncSimulator(graph, automata, byzantine_automatons, limit, link_failure_prob)
elif args.type == ASYNC:
if args.random_ids:
simulator = AsyncSimulatorWithRandomUID(graph, automata, byzantine_automatons, limit, link_failure_prob)
else:
simulator = AsyncSimulator(graph, automata, byzantine_automatons, limit, link_failure_prob)
elif args.type == ORDERED_ASYNC:
if args.random_ids:
simulator = OrderedAsyncSimulatorWithRandomUID(graph, automata, byzantine_automatons, limit,
link_failure_prob)
else:
simulator = OrderedAsyncSimulator(graph, automata, byzantine_automatons, limit, link_failure_prob)
simulator.run()
json.dump({
'graph': simulator.graph.to_dict(),
'steps': simulator.details,
}, args.output)
print(f'Total simulation took {(datetime.now() - start_time).total_seconds()} seconds.', file=sys.stderr)
if __name__ == '__main__':
run_cli()