rbsim 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/.hgignore +6 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +12 -0
  5. data/Gemfile.lock +66 -0
  6. data/LICENSE.txt +674 -0
  7. data/README.md +960 -0
  8. data/TODO +28 -0
  9. data/basic_sim.rb +62 -0
  10. data/fast-tcpn.rb +3 -0
  11. data/lib/rbsim.rb +14 -0
  12. data/lib/rbsim/dsl.rb +30 -0
  13. data/lib/rbsim/dsl/infrastructure.rb +48 -0
  14. data/lib/rbsim/dsl/mapping.rb +32 -0
  15. data/lib/rbsim/dsl/process.rb +129 -0
  16. data/lib/rbsim/dsl/program.rb +10 -0
  17. data/lib/rbsim/experiment.rb +110 -0
  18. data/lib/rbsim/hlmodel.rb +25 -0
  19. data/lib/rbsim/hlmodel/infrastructure.rb +116 -0
  20. data/lib/rbsim/hlmodel/mapping.rb +5 -0
  21. data/lib/rbsim/hlmodel/process.rb +152 -0
  22. data/lib/rbsim/numeric_units.rb +107 -0
  23. data/lib/rbsim/simulator.rb +184 -0
  24. data/lib/rbsim/statistics.rb +77 -0
  25. data/lib/rbsim/tokens.rb +146 -0
  26. data/lib/rbsim/version.rb +3 -0
  27. data/new_process.rb +49 -0
  28. data/rbsim.gemspec +42 -0
  29. data/show_readme.rb +15 -0
  30. data/sim.rb +142 -0
  31. data/sim_bamboo.rb +251 -0
  32. data/sim_process.rb +83 -0
  33. data/sim_process_dsl.rb +58 -0
  34. data/spec/dsl/infrastructure_nets_spec.rb +39 -0
  35. data/spec/dsl/infrastructure_nodes_spec.rb +72 -0
  36. data/spec/dsl/infrastructure_routes_spec.rb +44 -0
  37. data/spec/dsl/mapping_spec.rb +70 -0
  38. data/spec/dsl/process_spec.rb +56 -0
  39. data/spec/dsl/program_spec.rb +36 -0
  40. data/spec/dsl_and_hlmodel/new_process_spec.rb +235 -0
  41. data/spec/hlmodel/net_spec.rb +112 -0
  42. data/spec/hlmodel/process_spec.rb +242 -0
  43. data/spec/hlmodel/route_spec.rb +47 -0
  44. data/spec/hlmodel/routes_spec.rb +44 -0
  45. data/spec/integration/basic_simulation_spec.rb +104 -0
  46. data/spec/integration/net_spec.rb +44 -0
  47. data/spec/integration/process_spec.rb +117 -0
  48. data/spec/integration/rbsim_spec.rb +40 -0
  49. data/spec/simulator/logger_spec.rb +35 -0
  50. data/spec/simulator/stats_spec.rb +93 -0
  51. data/spec/spec_helper.rb +26 -0
  52. data/spec/statistics_spec.rb +300 -0
  53. data/spec/tcpn/add_route_spec.rb +55 -0
  54. data/spec/tcpn/cpu_spec.rb +53 -0
  55. data/spec/tcpn/map_data_spec.rb +37 -0
  56. data/spec/tcpn/network_spec.rb +163 -0
  57. data/spec/tcpn/register_event_spec.rb +48 -0
  58. data/spec/tcpn/route_to_self_spec.rb +53 -0
  59. data/spec/tcpn/stats_spec.rb +77 -0
  60. data/spec/tokens/data_queue_obsolete.rb +121 -0
  61. data/spec/tokens/data_queue_spec.rb +111 -0
  62. data/spec/units_spec.rb +48 -0
  63. data/tcpn/model.rb +6 -0
  64. data/tcpn/model/add_route.rb +78 -0
  65. data/tcpn/model/application.rb +250 -0
  66. data/tcpn/model/cpu.rb +75 -0
  67. data/tcpn/model/map_data.rb +42 -0
  68. data/tcpn/model/network.rb +108 -0
  69. data/tcpn/model/register_event.rb +89 -0
  70. data/tcpn/model/stats.rb +46 -0
  71. metadata +221 -0
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe "RBSim#dsl" do
4
+ context "model with routes" do
5
+
6
+ let :model do
7
+ RBSim.dsl do
8
+
9
+ route from: :node01, to: :node02, via: [ :net01, :net02 ]
10
+ route from: :node04, to: :node05, via: [ :net07, :net01 ], twoway: true
11
+ route from: :node06, to: :node07, via: [ :net07, :net01 ], twoway: :true
12
+
13
+ end
14
+ end
15
+
16
+ subject { model.routes }
17
+
18
+ it "has route from :node01 to :node02" do
19
+ expect(subject.find :node01, :node02).not_to be nil
20
+ end
21
+
22
+ it "has no route from :node02 to :node01" do
23
+ expect(subject.find :node02, :node01).to be nil
24
+ end
25
+
26
+ it "has route from :node04 to :node05" do
27
+ expect(subject.find :node04, :node05).not_to be nil
28
+ end
29
+
30
+ it "has route from :node05 to :node04" do
31
+ expect(subject.find :node05, :node04).not_to be nil
32
+ end
33
+
34
+ it "has route from :node06 to :node07" do
35
+ expect(subject.find :node06, :node07).not_to be nil
36
+ end
37
+
38
+ it "has route from :node07 to :node06" do
39
+ expect(subject.find :node07, :node06).not_to be nil
40
+ end
41
+
42
+
43
+ end
44
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe 'RBSim#dsl' do
4
+
5
+ context "with mapping" do
6
+
7
+ let(:model) do
8
+ RBSim.dsl do
9
+
10
+ put :client, on: :node01
11
+ put process: :worker1, on: :node01
12
+ put on: :node02, process: :worker2
13
+
14
+ end
15
+ end
16
+
17
+ it "has :client on :node01" do
18
+ expect(model.mapping[:client]).to eq :node01
19
+ end
20
+
21
+ it "has :worker1 on :node01" do
22
+ expect(model.mapping[:worker1]).to eq :node01
23
+ end
24
+
25
+ it "has :worker2 on :node02" do
26
+ expect(model.mapping[:worker2]).to eq :node02
27
+ end
28
+
29
+ end
30
+
31
+ context "with mapping without node" do
32
+ it "raises error" do
33
+ expect do
34
+ RBSim.dsl do
35
+ put :client
36
+ end
37
+ end.to raise_error RuntimeError
38
+ end
39
+ end
40
+
41
+ context "with mapping without process" do
42
+ it "raises error" do
43
+ expect do
44
+ RBSim.dsl do
45
+ put nil, on: :node01
46
+ end
47
+ end.to raise_error RuntimeError
48
+ end
49
+ end
50
+
51
+ context "with mapping defined by Hash without process" do
52
+ it "raises error" do
53
+ expect do
54
+ RBSim.dsl do
55
+ put on: :node01
56
+ end
57
+ end.to raise_error RuntimeError
58
+ end
59
+ end
60
+
61
+ context "with mapping defined by Hash without node" do
62
+ it "raises error" do
63
+ expect do
64
+ RBSim.dsl do
65
+ put process: :client
66
+ end
67
+ end.to raise_error RuntimeError
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe 'RBSim#dsl' do
4
+
5
+ shared_examples 'process defined' do
6
+
7
+ it "has one process" do
8
+ expect(model.processes.size).to eq(1)
9
+ end
10
+
11
+ it "has process :sender1" do
12
+ expect(model.processes[:sender1]).not_to be_nil
13
+ end
14
+
15
+ it "has 2 events in event_queue" do
16
+ expect(model.processes[:sender1].event_queue_size).to eq(2)
17
+ end
18
+ end
19
+
20
+ context "with processes defined by block" do
21
+
22
+ let(:model) do
23
+ RBSim.dsl do
24
+
25
+ new_process :sender1 do
26
+ delay_for time: 100
27
+ cpu do |cpu|
28
+ 10000/cpu.performance
29
+ end
30
+ end
31
+
32
+ end
33
+ end
34
+
35
+ include_examples 'process defined'
36
+
37
+ end
38
+
39
+ context "with processes defined by program" do
40
+ let(:model) do
41
+ RBSim.dsl do
42
+ program :sender1_prg do |args|
43
+ delay_for time: args[:time]
44
+ cpu do |cpu|
45
+ args[:volume]/cpu.performance
46
+ end
47
+ end
48
+ new_process :sender1, program: :sender1_prg, args: { time: 100, volume: 10000 }
49
+ end
50
+ end
51
+
52
+ include_examples 'process defined'
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe 'RBSim#dsl' do
4
+
5
+ context "with two programs" do
6
+
7
+ let(:model) do
8
+ RBSim.dsl do
9
+
10
+ program :waiter do |time|
11
+ delay_for time: time
12
+ end
13
+
14
+ program :worker do |volume|
15
+ cpu do |cpu|
16
+ volume * volume / cpu.performance
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+
23
+ it "has two programs" do
24
+ expect(model.programs.size).to eq(2)
25
+ end
26
+
27
+ it "has program called :waiter" do
28
+ expect(model.programs[:waiter]).not_to be_nil
29
+ end
30
+
31
+ it "has program called :volume" do
32
+ expect(model.programs[:worker]).not_to be_nil
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,235 @@
1
+ require 'spec_helper'
2
+ require 'pry'
3
+
4
+ # Test behavior of HLModel::Process created with
5
+ # DSL new_process statement
6
+ describe "HLModel::Process created with DSL#new_process" do
7
+
8
+ let :model do
9
+ RBSim.dsl do
10
+ new_process :worker do
11
+ stats_start tag: :work, group_name: 'worker1'
12
+ on_event :data do |volume|
13
+ delay_for 200
14
+ cpu do |c|
15
+ 20/c.performance
16
+ end
17
+ end
18
+ delay_for 100
19
+ stats_stop tag: :work, group_name: 'worker1'
20
+ stats tag: :doing_something, group_name: 'worker1'
21
+ cpu do |cpu|
22
+ 100/cpu.performance
23
+ end
24
+ new_process :child do
25
+ delay_for 400
26
+ end
27
+ register_event :data, args: 1000
28
+ send_data to: :child, size: 1024, type: :hello, content: "Hello!"
29
+ log "finished main, will serve events"
30
+ end
31
+ end
32
+ end
33
+
34
+ let :process do
35
+ p = model.processes[:worker]
36
+ p.node = :node01
37
+ p
38
+ end
39
+
40
+ module NewProcessSpec
41
+ class CPU
42
+ def performance
43
+ 20
44
+ end
45
+ end
46
+ end
47
+
48
+ it "has correct behavior" do
49
+ expect(model.processes.size).to eq(1)
50
+
51
+ event = process.serve_system_event :stats_start
52
+ expect(event).to eq({name: :stats_start, args: { tag: :work, group_name: 'worker1'} })
53
+
54
+ event = process.serve_system_event :delay_for
55
+ expect(event).to eq({name: :delay_for, args: { time: 100 }})
56
+
57
+ event = process.serve_system_event :stats_stop
58
+ expect(event).to eq({name: :stats_stop, args: { tag: :work, group_name: 'worker1' } })
59
+
60
+ event = process.serve_system_event :stats
61
+ expect(event).to eq({name: :stats, args: { tag: :doing_something, group_name: 'worker1' } })
62
+
63
+ event = process.serve_system_event :cpu
64
+ expect(event[:name]).to eq(:cpu)
65
+ # CPU time computed for specified CPU
66
+ expect(event[:args][:block].call NewProcessSpec::CPU.new).to eq(5)
67
+
68
+ # new process
69
+ event = process.serve_system_event :new_process
70
+ new_process = event[:args][:constructor].call event[:args][:constructor_args]
71
+ expect(model.processes.size).to eq(2)
72
+ expect(model.processes[:child]).not_to be_nil
73
+ expect(model.processes[:child]).to eq(new_process)
74
+ # serve event of the new process
75
+ event = new_process.serve_system_event :delay_for
76
+ expect(event).to eq({name: :delay_for, args: { time: 400 }})
77
+
78
+
79
+ # old process again
80
+ # user register_event
81
+ expect {
82
+ e = process.serve_system_event :register_event
83
+ event = e[:args][:event]
84
+ delay = e[:args][:delay]
85
+ args = e[:args][:event_args]
86
+ expect(e[:name]).to eq(:register_event)
87
+ expect(event).to eq(:data)
88
+ expect(delay).to eq(0)
89
+ expect(args).to eq(1000)
90
+ process.enqueue_event(event, args)
91
+ #expect(process.event_queue_size).to eq(4)
92
+ }.not_to change(process, :event_queue_size) # register_event dequeued, new event enqueued
93
+
94
+
95
+ # send_data
96
+ event = process.serve_system_event :send_data
97
+ expect(event[:name]).to eq(:send_data)
98
+ # CPU time computed for specified CPU
99
+ expect(event[:args]).to eq(to: :child, size: 1024, type: :hello, content: "Hello!")
100
+
101
+ # log
102
+ event = process.serve_system_event :log
103
+ expect(event[:name]).to eq(:log)
104
+ expect(event[:args]).to eq("finished main, will serve events")
105
+
106
+
107
+
108
+ # user event :data registered by :register_event, its handler will be run
109
+ # in the future when time comes
110
+ p = process.serve_user_event
111
+ expect(p).to eq(process) # returns modified process
112
+
113
+ # Events created by serving the the :data user event above follow:
114
+ event = process.serve_system_event :delay_for
115
+ expect(event).to eq({name: :delay_for, args: { time: 200 }})
116
+
117
+ event = process.serve_system_event :cpu
118
+ expect(event[:name]).to eq(:cpu)
119
+ # CPU time computed for specified CPU
120
+ expect(event[:args][:block].call NewProcessSpec::CPU.new).to eq(1)
121
+
122
+
123
+ end
124
+
125
+ describe "#event_time" do
126
+ let :model do
127
+ RBSim.dsl do
128
+ new_process :worker do
129
+
130
+ on_event :start do
131
+ start_time = event_time
132
+ register_event :next_one, delay: 100.seconds
133
+ end
134
+
135
+ on_event :next_one do
136
+ next_time = event_time
137
+ end
138
+
139
+ register_event :start
140
+ end
141
+ end
142
+ end
143
+
144
+ it "returns time reported by simulator" do
145
+ simulator = double("simulator")
146
+ expect(simulator).to receive(:clock).twice
147
+ model.simulator = simulator
148
+
149
+ e = process.serve_system_event :register_event
150
+ process.enqueue_event e[:args][:event], e[:args][:event_args]
151
+
152
+ process.serve_user_event # :start
153
+
154
+ process.serve_system_event :register_event
155
+ process.enqueue_event e[:args][:event], e[:args][:event_args]
156
+
157
+ process.serve_user_event # :next_one
158
+ end
159
+
160
+ end
161
+
162
+ describe "#function statement" do
163
+ describe "defines function with access to variable values in correct context" do
164
+ let :model do
165
+ RBSim.dsl do
166
+ new_process :worker do
167
+ @variable = :initial_value
168
+
169
+ function :do_something do
170
+ log @variable
171
+ end
172
+
173
+ on_event :start do
174
+ do_something
175
+ end
176
+
177
+ register_event :start
178
+ end
179
+ end
180
+ end
181
+
182
+ it "function reads correct values from variables" do
183
+ e = process.serve_system_event :register_event
184
+ process.enqueue_event e[:args][:event], e[:args][:event_args]
185
+
186
+ # :start
187
+ process.serve_user_event
188
+
189
+ # value of variable logged by the function
190
+ e = process.serve_system_event :log
191
+
192
+ expect(e[:name]).to eq :log
193
+ expect(e[:args]).to eq :initial_value
194
+
195
+ end
196
+ end
197
+
198
+ describe "defines function with access to correct 'self'" do
199
+ let :model do
200
+ RBSim.dsl do
201
+ new_process :worker do
202
+
203
+ function :do_something do
204
+ self
205
+ end
206
+
207
+ on_event :start do
208
+ log self
209
+ log do_something
210
+ end
211
+
212
+ register_event :start
213
+ end
214
+ end
215
+ end
216
+
217
+ it "'self' in function equals to 'self' in calling block" do
218
+ e = process.serve_system_event :register_event
219
+ process.enqueue_event e[:args][:event], e[:args][:event_args]
220
+
221
+ # :start
222
+ process.serve_user_event
223
+
224
+ # values of variables 'self'
225
+ # logged by the function...
226
+ log_function = process.serve_system_event :log
227
+ # ...and logged by the action handler block
228
+ log_block = process.serve_system_event :log
229
+
230
+ expect(log_function[:args].object_id).to eq log_block[:args].object_id
231
+ end
232
+ end
233
+
234
+ end
235
+ end
@@ -0,0 +1,112 @@
1
+ require 'spec_helper'
2
+
3
+ describe RBSim::HLModel::Net do
4
+ describe "drop decision" do
5
+ it "is always the same for two clones of the same net" do
6
+ net = RBSim::HLModel::Net.new :net01, 1024, 10, 0.5
7
+ equal_times = 1000.times.reduce(0) do |a,v|
8
+ net_clone = net.clone
9
+ if net.drop? == net_clone.drop?
10
+ a + 1
11
+ else
12
+ a
13
+ end
14
+ end
15
+ expect(equal_times).to eq 1000
16
+ end
17
+ end
18
+
19
+ describe "drop probability" do
20
+
21
+ it "defaults to 0" do
22
+ net = RBSim::HLModel::Net.new :net01, 1024, 10
23
+ expect(net.drop).to eq 0
24
+ end
25
+
26
+ it "can be 0" do
27
+ expect {
28
+ RBSim::HLModel::Net.new :net01, 1024, 10, 0
29
+ }.not_to raise_error
30
+ end
31
+
32
+ it "can be 1" do
33
+ expect {
34
+ RBSim::HLModel::Net.new :net01, 1024, 10, 1
35
+ }.not_to raise_error
36
+ end
37
+
38
+ it "can be 0.5" do
39
+ expect {
40
+ RBSim::HLModel::Net.new :net01, 1024, 10, 0.5
41
+ }.not_to raise_error
42
+ end
43
+
44
+ it "can be 0.3" do
45
+ expect {
46
+ RBSim::HLModel::Net.new :net01, 1024, 10, 0.3
47
+ }.not_to raise_error
48
+ end
49
+
50
+ it "cannot be 1.3" do
51
+ expect {
52
+ RBSim::HLModel::Net.new :net01, 1024, 10, 1.3
53
+ }.to raise_error
54
+ end
55
+
56
+ it "cannot be -1" do
57
+ expect {
58
+ RBSim::HLModel::Net.new :net01, 1024, 10, -1
59
+ }.to raise_error
60
+ end
61
+
62
+ it "can be a lambda" do
63
+ expect {
64
+ RBSim::HLModel::Net.new :net01, 1024, 10, -> { true }
65
+ }.not_to raise_error
66
+ end
67
+
68
+ it "can be a Proc" do
69
+ expect {
70
+ RBSim::HLModel::Net.new :net01, 1024, 10, Proc.new { true }
71
+ }.not_to raise_error
72
+ end
73
+
74
+ describe "given as float" do
75
+ it "drops all packets if euqlas 1" do
76
+ net = RBSim::HLModel::Net.new :net01, 1024, 10, 1
77
+ dropped = 100.times.reduce(0) { |a, v| net.drop? ? a + 1 : a }
78
+ expect(dropped).to eq 100
79
+ end
80
+
81
+ it "drops no packets if euqlas 1" do
82
+ net = RBSim::HLModel::Net.new :net01, 1024, 10, 0
83
+ dropped = 100.times.reduce(0) { |a, v| net.drop? ? a + 1 : a }
84
+ expect(dropped).to eq 0
85
+ end
86
+
87
+ it "drops half of the packets if euqlas 0.5" do
88
+ net = RBSim::HLModel::Net.new :net01, 1024, 10, 0.5
89
+ dropped = 1000.times.reduce(0) { |a, v| net.drop? ? a + 1 : a }
90
+ expect(dropped).to be_within(100).of(500)
91
+ end
92
+
93
+ end
94
+
95
+ describe "given as lambda" do
96
+ describe "if true" do
97
+ it "drops packet" do
98
+ net = RBSim::HLModel::Net.new :net01, 1024, 10, -> { true }
99
+ expect(net.drop?).to be true
100
+ end
101
+ end
102
+
103
+ describe "if false" do
104
+ it "does not drop packet" do
105
+ net = RBSim::HLModel::Net.new :net01, 1024, 10, -> { false }
106
+ expect(net.drop?).to be false
107
+ end
108
+ end
109
+
110
+ end
111
+ end
112
+ end