ruby-load 0.4.8 → 0.5
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.
- 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
|