ruby-load 0.4.8 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/load/client_command_line.rb +15 -13
- data/lib/load/http_report.rb +21 -19
- data/lib/load/load_manager.rb +2 -4
- data/lib/load/load_node.rb +29 -28
- data/lib/load/load_ramp_up.rb +17 -19
- data/lib/load/load_reporter.rb +10 -11
- data/lib/load/load_test.rb +19 -24
- data/lib/load/load_test_schedule.rb +11 -12
- data/lib/load/monitors/file_io_monitor.rb +5 -7
- data/lib/load/monitors/network_monitor.rb +2 -4
- data/lib/load/single_run/single_runner.rb +46 -0
- data/lib/{ruby_load.rb → ruby-load.rb} +0 -0
- metadata +51 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a2ce05fea4ef96b5f292c20662c9adb94c489a1
|
4
|
+
data.tar.gz: 6b31d0138a1ba3b81e769d42940d50ba95a47c41
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 839188c339e7003170725acdd25e91af4ef118745c456f7ba43fc3045188880a63c5f282d31121e69a6d4642fff6ac5737fe1c42cf1aee16ff67473a41a92e9f
|
7
|
+
data.tar.gz: edec983bbd47f7339d881fe1610d73f77e8baeead9995c01eb4708eff1c7959106a98aacc9d37d027b1c224337bb05f09d03e100bf5ed9870e0e78134374c8ba
|
@@ -16,7 +16,7 @@ class ClientCommandLine
|
|
16
16
|
|
17
17
|
def launch(args)
|
18
18
|
require_directory("custom")
|
19
|
-
puts "
|
19
|
+
puts "Loading It!"
|
20
20
|
index = 0
|
21
21
|
main_command = args[0]
|
22
22
|
puts "Command: #{main_command}"
|
@@ -60,13 +60,13 @@ class ClientCommandLine
|
|
60
60
|
end
|
61
61
|
|
62
62
|
uri = "http://#{server_address}/client"
|
63
|
-
puts "
|
63
|
+
puts "Load Mgr Server: #{uri}"
|
64
64
|
create_run(node_count, configuration_file_name, server_address, @target_server)
|
65
65
|
|
66
66
|
launch_node_command = "\nTo Start Nodes:\n"
|
67
67
|
@node_info_json.each do |node_config|
|
68
68
|
code = node_config["code"]
|
69
|
-
launch_node_command += " ruby
|
69
|
+
launch_node_command += " ruby ruby_load.rb node -c #{code} -s #{server_address} -r #{@run_id}\n"
|
70
70
|
end
|
71
71
|
|
72
72
|
puts "
|
@@ -79,22 +79,23 @@ class ClientCommandLine
|
|
79
79
|
|
80
80
|
elsif (main_command == "node")
|
81
81
|
@run_id = nil
|
82
|
-
load_node = process_node_command(args)
|
82
|
+
#load_node = process_node_command(args)
|
83
83
|
else
|
84
84
|
help_text =
|
85
85
|
"Usage:
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
load run -n /node_count/ -d /definition code/ {start with this process being the only node}
|
87
|
+
load node m {m is number of nodes, returns the run id for the node start up}
|
88
|
+
load node -r /run_id/ {starts one of the nodes for a run}
|
89
89
|
"
|
90
90
|
puts help_text
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
def create_run(node_count, configuration_file_name,
|
95
|
-
messenger = HttpReport.new(
|
96
|
-
|
97
|
-
@
|
94
|
+
def create_run(node_count, configuration_file_name, load_server_address, target_server)
|
95
|
+
messenger = HttpReport.new(load_server_address)
|
96
|
+
run_info= messenger.run_create({ node_count: node_count, config_file_name: configuration_file_name, target_server: target_server})
|
97
|
+
@run_id = run_info['id']
|
98
|
+
@node_info_json = run_info['nodes']
|
98
99
|
end
|
99
100
|
|
100
101
|
def process_node_command(args)
|
@@ -124,8 +125,9 @@ class ClientCommandLine
|
|
124
125
|
return load_node
|
125
126
|
end
|
126
127
|
|
127
|
-
def launch_node(run_id,
|
128
|
-
load_node = LoadNode.new(run_id,
|
128
|
+
def launch_node(run_id, load_server_address, node_code)
|
129
|
+
load_node = LoadNode.new(run_id, load_server_address, node_code)
|
130
|
+
return load_node
|
129
131
|
end
|
130
132
|
|
131
133
|
end
|
data/lib/load/http_report.rb
CHANGED
@@ -2,15 +2,16 @@ require "json"
|
|
2
2
|
require "net/http"
|
3
3
|
|
4
4
|
class HttpReport
|
5
|
-
|
5
|
+
|
6
6
|
def initialize(server_address)
|
7
|
+
raise "No server address" if (!server_address)
|
7
8
|
@server = server_address
|
8
9
|
end
|
9
10
|
|
10
11
|
def server_address
|
11
12
|
return "http://#{@server}/client"
|
12
13
|
end
|
13
|
-
|
14
|
+
|
14
15
|
def post(action, params)
|
15
16
|
address = server_address + action
|
16
17
|
puts "Posting to: #{address}, Params: #{params}"
|
@@ -20,18 +21,19 @@ class HttpReport
|
|
20
21
|
rescue Errno::ETIMEDOUT => error
|
21
22
|
raise "Communication with server error: #{error} Address: #{uri}"
|
22
23
|
end
|
23
|
-
|
24
|
+
|
24
25
|
if (response.code != "200")
|
25
26
|
puts "Action: #{action} Response: #{response.code} Response body: #{response.body}"
|
26
|
-
|
27
|
+
puts "Action: #{action} Response: #{response.code}"
|
28
|
+
raise "Bad response from load http: #{response.code}"
|
27
29
|
end
|
28
30
|
return response.body
|
29
31
|
end
|
30
|
-
|
32
|
+
|
31
33
|
def node_finished(params)
|
32
34
|
post "/node_finished", params
|
33
35
|
end
|
34
|
-
|
36
|
+
|
35
37
|
def report_result(run_id, node_id, test_code, wasp_id, run_at_millis, time, result)
|
36
38
|
response = nil
|
37
39
|
begin
|
@@ -45,7 +47,7 @@ class HttpReport
|
|
45
47
|
end
|
46
48
|
return response
|
47
49
|
end
|
48
|
-
|
50
|
+
|
49
51
|
def status_for_test(run_id, wasp_id)
|
50
52
|
# Checking for kill or finished run.
|
51
53
|
response = post("/status_for_test", {"run_id" => run_id, 'wasp_id' => wasp_id})
|
@@ -54,6 +56,7 @@ class HttpReport
|
|
54
56
|
|
55
57
|
def report_load_to_server(run_id, time, load_count)
|
56
58
|
response = post "/load", {"run_id" => run_id, "time" => time, "load" => load_count}
|
59
|
+
return response
|
57
60
|
end
|
58
61
|
|
59
62
|
def node_register(params)
|
@@ -61,13 +64,13 @@ class HttpReport
|
|
61
64
|
data = JSON.parse(response)
|
62
65
|
return data
|
63
66
|
end
|
64
|
-
|
67
|
+
|
65
68
|
def node_monitors(params)
|
66
69
|
response = post("/node_monitors", params)
|
67
70
|
data = JSON.parse(response)
|
68
71
|
return data
|
69
72
|
end
|
70
|
-
|
73
|
+
|
71
74
|
|
72
75
|
def node_start?(params)
|
73
76
|
response = post("/node_ask_to_start", params)
|
@@ -81,12 +84,12 @@ class HttpReport
|
|
81
84
|
data = JSON.parse(response)
|
82
85
|
return data
|
83
86
|
end
|
84
|
-
|
87
|
+
|
85
88
|
def node_ready(params)
|
86
89
|
response = post("/node_ready", params)
|
87
90
|
return response
|
88
91
|
end
|
89
|
-
|
92
|
+
|
90
93
|
def run_create(params)
|
91
94
|
node_count = params[:node_count]
|
92
95
|
if (node_count == nil)
|
@@ -97,17 +100,16 @@ class HttpReport
|
|
97
100
|
if (params[:config_file_name] != nil)
|
98
101
|
file_name = params[:config_file_name]
|
99
102
|
config_from_file = ""
|
100
|
-
begin
|
103
|
+
begin
|
101
104
|
File.open(file_name, "r") do |f|
|
102
105
|
config_from_file = f.read()
|
103
106
|
end
|
104
107
|
params[:config_file_name] = file_name
|
105
|
-
# params[:configuration] = config_from_file
|
106
108
|
configuration = eval(config_from_file)
|
107
109
|
server_list = configuration[:servers]
|
108
110
|
raise "Configuration lacks 'servers' list" unless (server_list != nil)
|
109
111
|
target_server_address = server_list[params[:target_server].to_sym]
|
110
|
-
raise "Configuration lacks entry in 'servers' list for ':#{params[:target_server]}'\n #{server_list}" unless target_server_address != nil
|
112
|
+
raise "Configuration lacks entry in 'servers' list for target: ':#{params[:target_server]}'\n #{server_list}" unless target_server_address != nil
|
111
113
|
params[:configuration] = configuration.to_s
|
112
114
|
params[:config_code] = configuration[:code]
|
113
115
|
raise "'duration' not specified for run." unless configuration[:duration] != nil
|
@@ -117,16 +119,16 @@ class HttpReport
|
|
117
119
|
raise "Exception reading config from file(#{File::absolute_path(file_name)}): #{e.message}"
|
118
120
|
end
|
119
121
|
end
|
120
|
-
|
122
|
+
|
121
123
|
response = post("/run_create", params)
|
122
124
|
data = JSON.parse(response)
|
123
|
-
return data
|
125
|
+
return data
|
124
126
|
end
|
125
|
-
|
127
|
+
|
126
128
|
def run_node_info(params)
|
127
129
|
response = post("/run_node_info", params)
|
128
130
|
data = JSON.parse(response)
|
129
131
|
return data
|
130
132
|
end
|
131
|
-
|
132
|
-
end
|
133
|
+
|
134
|
+
end
|
data/lib/load/load_manager.rb
CHANGED
@@ -16,18 +16,16 @@ class LoadManager
|
|
16
16
|
puts "Load Manager: #{Process.pid}"
|
17
17
|
pids = []
|
18
18
|
|
19
|
-
definition_code = configuration[
|
19
|
+
definition_code = configuration['code']
|
20
20
|
@server_address = ENV["SERVER"] || "localhost:2233"
|
21
21
|
puts "Server address: #{@server_address}"
|
22
|
-
ENV[""]
|
23
|
-
|
24
22
|
|
25
23
|
if (ENV['SERVER'] == nil)
|
26
24
|
puts "No 'SERVER' env specified, creating local/minimal server to store results"
|
27
25
|
pids << fork {
|
28
26
|
@reporter = LoadReporter.new({server: @server_address})
|
29
27
|
while (@reporter.started == false)
|
30
|
-
puts "Cannot find
|
28
|
+
puts "Cannot find Load server"
|
31
29
|
sleep 1
|
32
30
|
end
|
33
31
|
}
|
data/lib/load/load_node.rb
CHANGED
@@ -6,16 +6,17 @@ require_relative "./monitors/file_io_monitor.rb"
|
|
6
6
|
require_relative "./monitors/network_monitor.rb"
|
7
7
|
require_relative "./test_factory.rb"
|
8
8
|
|
9
|
-
@@load_node_instance = nil
|
10
9
|
|
11
10
|
class LoadNode
|
11
|
+
@@load_node_instance = nil
|
12
|
+
|
12
13
|
attr_reader :node_id, :schedule, :duration_millis
|
13
14
|
attr_accessor :target_server, :target_code
|
14
|
-
|
15
|
+
|
15
16
|
def self.instance
|
16
17
|
return @@load_node_instance
|
17
18
|
end
|
18
|
-
|
19
|
+
|
19
20
|
def initialize(run_id, server_address, node_code = nil)
|
20
21
|
if (@@load_node_instance != nil)
|
21
22
|
raise "LoadNode instance initialized a second time"
|
@@ -36,7 +37,7 @@ class LoadNode
|
|
36
37
|
node_info = @messenger.node_register({run_id: @run_id, address: "#{Socket.gethostname}", code: node_code})
|
37
38
|
if (node_info['configuration'] == nil)
|
38
39
|
puts "Error starting node. Did run already complete?"
|
39
|
-
else
|
40
|
+
else
|
40
41
|
@configuration = eval(node_info['configuration'])
|
41
42
|
@node_id = node_info["id"].to_i
|
42
43
|
@node_code = node_info["code"]
|
@@ -52,7 +53,7 @@ class LoadNode
|
|
52
53
|
wait_for_finish
|
53
54
|
@messenger.node_finished({node_id: @node_id})
|
54
55
|
end
|
55
|
-
rescue Interrupt
|
56
|
+
rescue Interrupt
|
56
57
|
puts "NODE (#{@node_id}) - Interrupt signal received, quitting. [#{self.class}]"
|
57
58
|
rescue Exception => exc
|
58
59
|
puts "Exception in node: #{exc.message} \n" + exc.backtrace.join("\n")
|
@@ -63,17 +64,17 @@ class LoadNode
|
|
63
64
|
end
|
64
65
|
end
|
65
66
|
|
66
|
-
def report_block_result(test_code,
|
67
|
-
@messenger.report_result(@run_id, @node_id, test_code,
|
67
|
+
def report_block_result(test_code, runner_id, time_ellapsed, benchmark_time, result)
|
68
|
+
@messenger.report_result(@run_id, @node_id, test_code, runner_id, time_ellapsed, benchmark_time, result)
|
68
69
|
end
|
69
|
-
|
70
|
-
|
71
|
-
def write_pid_to_file(pid)
|
70
|
+
|
71
|
+
|
72
|
+
def write_pid_to_file(pid)
|
72
73
|
open('node_pids_#{@node_id}.pid', 'a') { |f|
|
73
74
|
f.puts "#{pid}\n"
|
74
75
|
}
|
75
76
|
end
|
76
|
-
|
77
|
+
|
77
78
|
def launch_node_tests
|
78
79
|
@load_tests.each do |test|
|
79
80
|
pid = fork {
|
@@ -98,8 +99,8 @@ class LoadNode
|
|
98
99
|
end
|
99
100
|
puts "All Nodes Launched. Node (#{@node_code}) can start now "
|
100
101
|
end
|
101
|
-
|
102
|
-
|
102
|
+
|
103
|
+
|
103
104
|
def wait_for_finish
|
104
105
|
@start_time = Time.now.to_i
|
105
106
|
quit = false
|
@@ -113,7 +114,7 @@ class LoadNode
|
|
113
114
|
#puts "Node duration (#{ellapsed_time} secs) NOT reached: #{@duration_millis/1000} seconds."
|
114
115
|
end
|
115
116
|
@messenger.node_schedule({node_id: @node_id})
|
116
|
-
|
117
|
+
|
117
118
|
status = @messenger.status_for_test(@run_id, nil)
|
118
119
|
if (status['run_status'] == "killed")
|
119
120
|
puts "XXXXX RUN HAS BEEN KILLED - KILLING NODE: #{@wasp_id} XXXXXXX"
|
@@ -122,12 +123,12 @@ class LoadNode
|
|
122
123
|
puts "XXXXX RUN IS FINISHED - KILLING NODE: #{@wasp_id} XXXXXXX"
|
123
124
|
quit = true
|
124
125
|
end
|
125
|
-
|
126
|
+
|
126
127
|
end
|
127
128
|
puts "Node finished. ##{@node_code}"
|
128
129
|
end
|
129
|
-
|
130
|
-
|
130
|
+
|
131
|
+
|
131
132
|
def create_node_tests(node_id, node_schedule)
|
132
133
|
wasp_id = 1
|
133
134
|
load_tests = []
|
@@ -144,12 +145,12 @@ class LoadNode
|
|
144
145
|
test = @factory.create_test(test_name, @target_code, test_config)
|
145
146
|
test.index = @test_index
|
146
147
|
@test_index += 1
|
147
|
-
|
148
|
+
|
148
149
|
load_test = LoadTest.new(self, @run_id, node_id, wasp_id, test, events, @messenger)
|
149
150
|
load_tests << load_test
|
150
151
|
wasp_id += 1
|
151
152
|
end
|
152
|
-
|
153
|
+
|
153
154
|
node_monitors = @messenger.node_monitors( {node_id: @node_id} )
|
154
155
|
node_monitors.each do |monitor_config|
|
155
156
|
type = monitor_config["type"]
|
@@ -158,7 +159,7 @@ class LoadNode
|
|
158
159
|
if (name == nil)
|
159
160
|
name = "#{type.capitalize} Monitor"
|
160
161
|
end
|
161
|
-
|
162
|
+
|
162
163
|
if (type == "network")
|
163
164
|
puts "Config: #{monitor_config}"
|
164
165
|
address = monitor_config["address"]
|
@@ -172,16 +173,16 @@ class LoadNode
|
|
172
173
|
else
|
173
174
|
raise "Do no know how to handle monitor type: #{type} Name: #{name}"
|
174
175
|
end
|
175
|
-
|
176
|
+
|
176
177
|
events = [{"time" => "0", "action" => "run"}, {"time" => "#{duration}", "action" => "pause"}]
|
177
178
|
load_test = LoadTest.new(self, @run_id, node_id, wasp_id, monitor, events, @messenger)
|
178
179
|
load_tests << load_test
|
179
180
|
wasp_id += 1
|
180
181
|
end
|
181
|
-
|
182
|
+
|
182
183
|
return load_tests
|
183
184
|
end
|
184
|
-
|
185
|
+
|
185
186
|
def find_config_for_test(test_name)
|
186
187
|
test_configs = @configuration[:tests]
|
187
188
|
test_configs.each do |test_config|
|
@@ -191,7 +192,7 @@ class LoadNode
|
|
191
192
|
end
|
192
193
|
end
|
193
194
|
|
194
|
-
|
195
|
+
|
195
196
|
def kill_child_processes
|
196
197
|
# puts "=================================================================================="
|
197
198
|
# puts "Node Finished: #{@node_id}"
|
@@ -202,7 +203,7 @@ class LoadNode
|
|
202
203
|
# exit
|
203
204
|
# end
|
204
205
|
Process.kill('INT', -Process.getpgrp)
|
205
|
-
#
|
206
|
+
#
|
206
207
|
# @child_pids.each do |pid|
|
207
208
|
# begin
|
208
209
|
# puts "Killing: #{pid}"
|
@@ -212,6 +213,6 @@ class LoadNode
|
|
212
213
|
# end
|
213
214
|
# end
|
214
215
|
end
|
215
|
-
|
216
|
-
|
217
|
-
end
|
216
|
+
|
217
|
+
|
218
|
+
end
|
data/lib/load/load_ramp_up.rb
CHANGED
@@ -5,8 +5,8 @@ require_relative "./test_factory"
|
|
5
5
|
|
6
6
|
class LoadRampUp
|
7
7
|
attr_reader :tests
|
8
|
-
|
9
|
-
|
8
|
+
|
9
|
+
|
10
10
|
def initialize(run_id, target_code, configuration)
|
11
11
|
puts "Load Ramp Up created"
|
12
12
|
if (run_id == nil)
|
@@ -19,11 +19,9 @@ class LoadRampUp
|
|
19
19
|
@all_tests = []
|
20
20
|
@configuration = configuration
|
21
21
|
wasp_id = 0
|
22
|
-
|
22
|
+
|
23
23
|
@configuration[:tests].each do |test_config|
|
24
24
|
test_class = test_config[:test]
|
25
|
-
|
26
|
-
initial_count = test_config[:initial]
|
27
25
|
ramp_up_config = test_config[:ramp_up]
|
28
26
|
final_count = ramp_up_config[:final]
|
29
27
|
@tests[test_class] = []
|
@@ -49,7 +47,7 @@ class LoadRampUp
|
|
49
47
|
if (action == :run)
|
50
48
|
total_load += 1
|
51
49
|
end
|
52
|
-
end
|
50
|
+
end
|
53
51
|
report_load_to_server(@run_id, time, total_load)
|
54
52
|
end
|
55
53
|
end
|
@@ -65,7 +63,7 @@ class LoadRampUp
|
|
65
63
|
end
|
66
64
|
return last_time
|
67
65
|
end
|
68
|
-
|
66
|
+
|
69
67
|
|
70
68
|
def find_total_loads
|
71
69
|
load_at_times
|
@@ -80,21 +78,21 @@ class LoadRampUp
|
|
80
78
|
time += 1
|
81
79
|
end
|
82
80
|
end
|
83
|
-
|
84
|
-
|
81
|
+
|
82
|
+
|
85
83
|
def assign_schedules_to_tests(test_config, load_tests)
|
86
84
|
ramp_up = test_config[:ramp_up]
|
87
85
|
initial_count = test_config[:initial]
|
88
|
-
|
86
|
+
|
89
87
|
load_tests.each do |test|
|
90
88
|
test.schedule.add(0, :pause)
|
91
89
|
end
|
92
|
-
|
90
|
+
|
93
91
|
(0..initial_count - 1).each do |index|
|
94
92
|
test = load_tests[index]
|
95
93
|
test.schedule.add(0, :run)
|
96
94
|
end
|
97
|
-
|
95
|
+
|
98
96
|
rate = ramp_up[:rate]
|
99
97
|
current_time = 0
|
100
98
|
tests_started = initial_count
|
@@ -103,10 +101,10 @@ class LoadRampUp
|
|
103
101
|
load_tests[tests_started].schedule.add(current_time, :run)
|
104
102
|
tests_started += 1
|
105
103
|
end
|
106
|
-
|
104
|
+
|
107
105
|
sustain_time = test_config[:sustain]
|
108
106
|
current_time += sustain_time
|
109
|
-
|
107
|
+
|
110
108
|
ramp_down = test_config[:ramp_down]
|
111
109
|
final_count = ramp_down[:final]
|
112
110
|
rate = ramp_down[:rate]
|
@@ -117,7 +115,7 @@ class LoadRampUp
|
|
117
115
|
end
|
118
116
|
end
|
119
117
|
|
120
|
-
|
118
|
+
|
121
119
|
|
122
120
|
def run
|
123
121
|
begin
|
@@ -141,19 +139,19 @@ class LoadRampUp
|
|
141
139
|
exit 0
|
142
140
|
end
|
143
141
|
|
144
|
-
|
142
|
+
|
145
143
|
def wait_for_kill_signal()
|
146
144
|
while (true) do
|
147
145
|
sleep 2000
|
148
146
|
end
|
149
147
|
end
|
150
|
-
|
151
|
-
|
148
|
+
|
149
|
+
|
152
150
|
def kill_pids(pids)
|
153
151
|
puts "Killing child processes"
|
154
152
|
pids.each do |pid|
|
155
153
|
Process.kill("INT", pid)
|
156
154
|
end
|
157
155
|
end
|
158
|
-
|
156
|
+
|
159
157
|
end
|
data/lib/load/load_reporter.rb
CHANGED
@@ -9,32 +9,31 @@ class LoadReporter
|
|
9
9
|
@started = false
|
10
10
|
@server_address = params[:server]
|
11
11
|
@current_load = 0
|
12
|
-
file_name = "data_#{Time.now.to_i}.txt"
|
13
12
|
@out_file = File.new("out.txt", "w")
|
14
13
|
port = params[:port] || 2233
|
15
14
|
puts "Starting server: http://#{Socket.gethostname}:#{port}"
|
16
15
|
server = HTTPServer.new(:Port=>2233,:DocumentRoot=>Dir::pwd )
|
17
16
|
trap("INT") {
|
18
|
-
puts "Server going down"
|
19
|
-
server.shutdown
|
17
|
+
puts "Server going down"
|
18
|
+
server.shutdown
|
20
19
|
}
|
21
|
-
|
20
|
+
|
22
21
|
server.mount_proc '/' do |request, response|
|
23
22
|
response.body = process_request(request)
|
24
23
|
end
|
25
|
-
server.start
|
24
|
+
server.start
|
26
25
|
@started = true
|
27
26
|
end
|
28
|
-
|
29
|
-
|
27
|
+
|
28
|
+
|
30
29
|
def process_request(request)
|
31
30
|
response = "
|
32
31
|
Current Load: #{@current_load}
|
33
32
|
Query String: #{request.query_string}
|
34
33
|
"
|
35
|
-
|
36
|
-
request.query.collect { | key, value |
|
37
|
-
#f.write("#{key}: #{value}\n")
|
34
|
+
|
35
|
+
request.query.collect { | key, value |
|
36
|
+
#f.write("#{key}: #{value}\n")
|
38
37
|
if (key == "load")
|
39
38
|
@current_load = value.to_i
|
40
39
|
response += "Current load changed to: #{@current_load}"
|
@@ -44,5 +43,5 @@ class LoadReporter
|
|
44
43
|
puts "RESPONSE: #{response}"
|
45
44
|
return response
|
46
45
|
end
|
47
|
-
|
46
|
+
|
48
47
|
end
|
data/lib/load/load_test.rb
CHANGED
@@ -9,10 +9,10 @@ require 'fileutils'
|
|
9
9
|
class LoadTest
|
10
10
|
PASSED = "passed"
|
11
11
|
FAILED = "failed"
|
12
|
-
|
12
|
+
|
13
13
|
attr_reader :wasp_id, :start_time, :test
|
14
14
|
attr_accessor :schedule
|
15
|
-
|
15
|
+
|
16
16
|
def initialize(owner, run_id, node_id, wasp_id, test, schedule_events, messenger = nil)
|
17
17
|
@owner = owner
|
18
18
|
test.owner = self
|
@@ -22,12 +22,11 @@ class LoadTest
|
|
22
22
|
@node_id = node_id
|
23
23
|
@wasp_id = wasp_id
|
24
24
|
@time_of_last_status_check = 0
|
25
|
-
|
25
|
+
|
26
26
|
@test = test
|
27
27
|
if (run_id == nil) || (run_id == 0)
|
28
28
|
raise "No run_id specified for load test"
|
29
29
|
end
|
30
|
-
test_code = self.class.name
|
31
30
|
@run_id = run_id
|
32
31
|
@name = "Test for #{test.test_code}"
|
33
32
|
end
|
@@ -35,7 +34,7 @@ class LoadTest
|
|
35
34
|
def log
|
36
35
|
return @logger
|
37
36
|
end
|
38
|
-
|
37
|
+
|
39
38
|
def create_logger
|
40
39
|
FileUtils.mkdir_p('./log/load') unless File.directory?('./log/load')
|
41
40
|
FileUtils.mkdir_p("./log/load/run_#{@run_id}") unless File.directory?("./log/load/run_#{@run_id}")
|
@@ -44,7 +43,7 @@ class LoadTest
|
|
44
43
|
@logger.level = Logger::DEBUG
|
45
44
|
@test.logger = @logger
|
46
45
|
end
|
47
|
-
|
46
|
+
|
48
47
|
def run
|
49
48
|
create_logger()
|
50
49
|
trap('INT') do
|
@@ -52,12 +51,11 @@ class LoadTest
|
|
52
51
|
#log.info "Wasp asked to die: #{test_code}:#{@wasp_id} Pid: #{Process.pid}"
|
53
52
|
exit 0
|
54
53
|
end
|
55
|
-
|
54
|
+
|
56
55
|
begin
|
57
56
|
@start_time = Time.now
|
58
57
|
@exit = false
|
59
58
|
while (!@exit)
|
60
|
-
result = FAILED
|
61
59
|
run_if_time_right(time_ellapsed_millis)
|
62
60
|
end
|
63
61
|
puts "End of run for wasp: #{@wasp_id}. Duration: #{duration_millis}"
|
@@ -76,7 +74,7 @@ class LoadTest
|
|
76
74
|
end
|
77
75
|
end
|
78
76
|
|
79
|
-
|
77
|
+
|
80
78
|
def run_if_time_right(current_time_millis)
|
81
79
|
benchmark_time = 0
|
82
80
|
if (current_time_millis >= duration_millis)
|
@@ -87,12 +85,12 @@ class LoadTest
|
|
87
85
|
if (current_action == :run)
|
88
86
|
#puts "Time is right. Test being performed"
|
89
87
|
result = PASSED
|
90
|
-
begin
|
88
|
+
begin
|
91
89
|
benchmark_time = Benchmark.realtime {
|
92
90
|
perform_test
|
93
91
|
}
|
94
92
|
log.info "Test completed normally in #{benchmark_time} seconds"
|
95
|
-
rescue SystemExit
|
93
|
+
rescue SystemExit
|
96
94
|
log.warn "Caught system exit signal. Exiting..."
|
97
95
|
@exit = true
|
98
96
|
rescue Exception => e
|
@@ -103,7 +101,7 @@ class LoadTest
|
|
103
101
|
end
|
104
102
|
puts "Test (#{@test.class}) produced exception: #{e.class} #{e.message} #{e.backtrace}"
|
105
103
|
end
|
106
|
-
|
104
|
+
|
107
105
|
custom_timing = @test.timing
|
108
106
|
if (custom_timing != nil)
|
109
107
|
benchmark_time = custom_timing
|
@@ -113,7 +111,7 @@ class LoadTest
|
|
113
111
|
#puts "Not running test. current_action = #{current_action}"
|
114
112
|
sleep 0.2
|
115
113
|
end
|
116
|
-
|
114
|
+
|
117
115
|
if (@exit == false)
|
118
116
|
time_since_last_status_check = current_time_millis - @time_of_last_status_check
|
119
117
|
if (time_since_last_status_check > 20*1000)
|
@@ -130,7 +128,7 @@ class LoadTest
|
|
130
128
|
end
|
131
129
|
end
|
132
130
|
end
|
133
|
-
|
131
|
+
|
134
132
|
|
135
133
|
|
136
134
|
def duration_millis
|
@@ -142,7 +140,7 @@ class LoadTest
|
|
142
140
|
last_run_time = event[:time]
|
143
141
|
end
|
144
142
|
end
|
145
|
-
|
143
|
+
|
146
144
|
if (last_run_time == nil)
|
147
145
|
raise "This test never finishes on it's own"
|
148
146
|
end
|
@@ -162,16 +160,16 @@ class LoadTest
|
|
162
160
|
def current_action
|
163
161
|
return current_action_for_time(time_ellapsed_millis)
|
164
162
|
end
|
165
|
-
|
163
|
+
|
166
164
|
def current_action_for_time(millis)
|
167
165
|
current_action = schedule.current_action(millis / 1000)
|
168
166
|
return current_action
|
169
167
|
end
|
170
|
-
|
168
|
+
|
171
169
|
def test_code
|
172
170
|
return @test.test_code
|
173
171
|
end
|
174
|
-
|
172
|
+
|
175
173
|
def to_s
|
176
174
|
return "I am only one wasp of a swarm. ##{@wasp_id}"
|
177
175
|
end
|
@@ -180,8 +178,8 @@ class LoadTest
|
|
180
178
|
if (value == false)
|
181
179
|
raise "Assertion failed"
|
182
180
|
end
|
183
|
-
end
|
184
|
-
|
181
|
+
end
|
182
|
+
|
185
183
|
def perform_test
|
186
184
|
@test.owner = self
|
187
185
|
@test.set_up
|
@@ -189,8 +187,5 @@ class LoadTest
|
|
189
187
|
@test.pause_after_run
|
190
188
|
@test.tear_down
|
191
189
|
end
|
192
|
-
|
193
|
-
end
|
194
|
-
|
195
|
-
|
196
190
|
|
191
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
class LoadTestSchedule
|
2
2
|
attr_accessor :events
|
3
|
-
|
3
|
+
|
4
4
|
def initialize
|
5
5
|
@events = []
|
6
6
|
@previous_action = nil
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def add(time, action)
|
10
10
|
if (action != @previous_action)
|
11
11
|
remove_action_at_time(time)
|
@@ -15,7 +15,7 @@ class LoadTestSchedule
|
|
15
15
|
end
|
16
16
|
@previous_action = action
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def load_json(schedule_events)
|
20
20
|
schedule_events.each do |event|
|
21
21
|
time = event["time"].to_i
|
@@ -23,7 +23,7 @@ class LoadTestSchedule
|
|
23
23
|
add(time, action)
|
24
24
|
end
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def remove_action_at_time(time)
|
28
28
|
(0..@events.length - 1).each do |i|
|
29
29
|
if (@events[i][:time] == time)
|
@@ -32,8 +32,8 @@ class LoadTestSchedule
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
35
|
-
|
36
|
-
|
35
|
+
|
36
|
+
|
37
37
|
def current_action(time)
|
38
38
|
event = current_event(time)
|
39
39
|
if (event == nil)
|
@@ -52,8 +52,8 @@ class LoadTestSchedule
|
|
52
52
|
return event[:action]
|
53
53
|
end
|
54
54
|
end
|
55
|
-
|
56
|
-
|
55
|
+
|
56
|
+
|
57
57
|
def current_event(time)
|
58
58
|
current_event = nil
|
59
59
|
@events.each do |event|
|
@@ -66,7 +66,6 @@ class LoadTestSchedule
|
|
66
66
|
|
67
67
|
|
68
68
|
def next_event(time)
|
69
|
-
current_event = nil
|
70
69
|
@events.each do |event|
|
71
70
|
if (event[:time] > time.to_i)
|
72
71
|
return event
|
@@ -74,6 +73,6 @@ class LoadTestSchedule
|
|
74
73
|
end
|
75
74
|
return @events.last
|
76
75
|
end
|
77
|
-
|
78
|
-
|
79
|
-
end
|
76
|
+
|
77
|
+
|
78
|
+
end
|
@@ -12,14 +12,14 @@ class FileIoMonitor < TimingTest
|
|
12
12
|
def run
|
13
13
|
file_name = "./log/file_io_bench_#{Time.now.to_i}.dat"
|
14
14
|
(1..200).each do |i|
|
15
|
-
File.open(file_name, 'w') { |file|
|
16
|
-
(1..1000).each do |
|
17
|
-
file.write("Test text #{
|
15
|
+
File.open(file_name, 'w') { |file|
|
16
|
+
(1..1000).each do |j|
|
17
|
+
file.write("Test text #{j} aohoasihdf oiahsdf pohiasdfha oisdhf aiousdfgho iausgdf oaia aiusdhfia hdfihdsfi ahsdfi ahudf \n")
|
18
18
|
file.flush
|
19
19
|
end
|
20
20
|
}
|
21
|
-
|
22
|
-
File.readlines(file_name).each do |line|
|
21
|
+
|
22
|
+
File.readlines(file_name).each do |line|
|
23
23
|
if (!line.start_with? "Test text")
|
24
24
|
raise "Error reading back file"
|
25
25
|
end
|
@@ -38,5 +38,3 @@ class FileIoMonitor < TimingTest
|
|
38
38
|
end
|
39
39
|
|
40
40
|
end
|
41
|
-
|
42
|
-
|
@@ -25,13 +25,13 @@ class NetworkMonitor < TimingTest
|
|
25
25
|
end
|
26
26
|
puts "Ping timing for 10 pings: #{timing}"
|
27
27
|
@timing = timing
|
28
|
-
rescue Exception
|
28
|
+
rescue Exception
|
29
29
|
@timing = nil
|
30
30
|
puts "Error pinging address: #{@address} => #{output}"
|
31
31
|
raise "Error pinging address: #{@address} => #{output}"
|
32
32
|
end
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
#64 bytes from localhost (127.0.0.1): icmp_req=4 ttl=64 time=0.015 ms
|
36
36
|
#64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.018 ms
|
37
37
|
|
@@ -44,5 +44,3 @@ class NetworkMonitor < TimingTest
|
|
44
44
|
end
|
45
45
|
|
46
46
|
end
|
47
|
-
|
48
|
-
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module SingleRunner
|
2
|
+
|
3
|
+
def report_block_result(test_code, wasp_id, time_ellapsed, benchmark_time, result, target_code)
|
4
|
+
puts "BLOCK RESULT (#{test_code}): #{result} Time: #{benchmark_time/1000} seconds "
|
5
|
+
end
|
6
|
+
|
7
|
+
def time_ellapsed_millis
|
8
|
+
return 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def log
|
12
|
+
logger = Logger.new(STDERR)
|
13
|
+
return logger
|
14
|
+
end
|
15
|
+
|
16
|
+
def error_count
|
17
|
+
return @error_count
|
18
|
+
end
|
19
|
+
|
20
|
+
def run_and_benchmark(test, target, params, iterations)
|
21
|
+
load_node = LoadNode.instance
|
22
|
+
if (LoadNode.instance == nil)
|
23
|
+
load_node = LoadNode.new(0, nil, nil)
|
24
|
+
end
|
25
|
+
# load_node.target_server = servers[target]
|
26
|
+
|
27
|
+
@error_count = 0
|
28
|
+
timings = []
|
29
|
+
logger = Logger.new(STDERR)
|
30
|
+
test.logger = logger
|
31
|
+
test.owner = self
|
32
|
+
test.params = params
|
33
|
+
test.set_up
|
34
|
+
|
35
|
+
(1..iterations).each do |loop_index|
|
36
|
+
puts "==============================================================="
|
37
|
+
time = Benchmark.realtime {
|
38
|
+
test.run
|
39
|
+
}
|
40
|
+
timings << time
|
41
|
+
puts "=================> Iteration: #{test.class} #{loop_index} Time: #{time} seconds"
|
42
|
+
end
|
43
|
+
test.tear_down
|
44
|
+
return timings
|
45
|
+
end
|
46
|
+
end
|
File without changes
|
metadata
CHANGED
@@ -1,15 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-load
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.5'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Moore
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2017-08-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: net-ping
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: retry_block
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.2.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.2.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.0'
|
13
55
|
description: Ruby Load Tester
|
14
56
|
email: m.moore.denver@gmail.com
|
15
57
|
executables: []
|
@@ -29,9 +71,10 @@ files:
|
|
29
71
|
- lib/load/monitors/file_io_monitor.rb
|
30
72
|
- lib/load/monitors/network_monitor.rb
|
31
73
|
- lib/load/monitors/ram_monitor.rb
|
74
|
+
- lib/load/single_run/single_runner.rb
|
32
75
|
- lib/load/test_factory.rb
|
33
76
|
- lib/load/timing_test.rb
|
34
|
-
- lib/
|
77
|
+
- lib/ruby-load.rb
|
35
78
|
homepage: ''
|
36
79
|
licenses:
|
37
80
|
- MIT
|
@@ -40,20 +83,20 @@ post_install_message:
|
|
40
83
|
rdoc_options: []
|
41
84
|
require_paths:
|
42
85
|
- lib
|
43
|
-
- lib/
|
86
|
+
- lib/load
|
44
87
|
required_ruby_version: !ruby/object:Gem::Requirement
|
45
88
|
requirements:
|
46
|
-
- -
|
89
|
+
- - ">="
|
47
90
|
- !ruby/object:Gem::Version
|
48
91
|
version: '0'
|
49
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
93
|
requirements:
|
51
|
-
- -
|
94
|
+
- - ">="
|
52
95
|
- !ruby/object:Gem::Version
|
53
96
|
version: '0'
|
54
97
|
requirements: []
|
55
98
|
rubyforge_project:
|
56
|
-
rubygems_version: 2.
|
99
|
+
rubygems_version: 2.6.12
|
57
100
|
signing_key:
|
58
101
|
specification_version: 4
|
59
102
|
summary: Ruby Load Tester
|