mu 5.7.9 → 5.7.10

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.
@@ -59,7 +59,7 @@ class Mu
59
59
  # Get har object and hosts
60
60
  har_file = @options.har_files[0]
61
61
  @har = Har.new har_file, @options, @ignores
62
- msl_file = File.open(@options.scenario,'w')
62
+ msl_file = File.open(@options.scenario,'w')
63
63
  created_musl = @har.generate msl_file
64
64
  msl_file.write created_musl
65
65
  msl_file.close
@@ -131,9 +131,9 @@ class Mu
131
131
  @options.strip_large_content = true
132
132
  @options.large_content_size = size
133
133
  end
134
- @opts.on( '--endpoint', 'One way communication' ) do
135
- @options.endpoint = true
136
- end
134
+ #@opts.on( '--endpoint', 'One way communication' ) do
135
+ # @options.endpoint = true
136
+ #end
137
137
  @opts.on( '-s', '--scenario [FILENAME]', 'Specify the msl filename to be created' ) do |scenario|
138
138
  @options.scenario = scenario
139
139
  end
@@ -15,79 +15,6 @@ class Mu
15
15
  help
16
16
  end
17
17
 
18
- # sets up, executes, and closes a Studio Scale test
19
- # * argv = command-line arguments , requires a scenario (-s) argument
20
- def cmd_run_file argv
21
- puts "\n***WARNING***\nThe following commands will be deprecated in a future release:"
22
- puts "cmd_runscale:run_file, cmd_runscale:run_dir, cmd_appid\n"
23
- puts "Please use 'cmd_runscale:run_files'"
24
- setup argv
25
-
26
- if not @hash['scenario']
27
- msg "scenario required", Logger::ERROR
28
- return help
29
- else
30
- if @hash['scenario'].include?(".msl")
31
- scenario = @hash['scenario']
32
- else # TODO: eventually, xml and mus file may be supported by scale api
33
- msg "only .msl files are currently supported", Logger::ERROR
34
- return help
35
- end
36
- end
37
-
38
- if not File.readable?(scenario)
39
- msg "*** Error: can't read scenario file #{scenario}", Logger::ERROR
40
- return
41
- end
42
-
43
- @api = Scale.new(@@mu_ip, @@mu_admin_user, @@mu_admin_pass)
44
- @api.configure("pattern", @cmd_line_pattern)
45
- @params = {}
46
- @params["dir"] = @dir
47
- @params["msl"] = scenario
48
- @params["hosts"] = @cmd_line_hosts
49
- run(scenario)
50
- @api.release
51
- end
52
-
53
- # sets up, executes, and closes a Studio Scale test for each scenario (.msl file) found in the specified directory
54
- # * argv = command-line arguments, requires a directory (-d) argument
55
- # * optional -r argument for recursive directory search (default is a flat directory)
56
- def cmd_run_dir argv
57
- puts "\n***WARNING***\nThe following commands will be deprecated in a future release:"
58
- puts "cmd_runscale:run_file, cmd_runscale:run_dir, cmd_appid\n"
59
- puts "Please use 'cmd_runscale:run_files'"
60
- setup argv
61
-
62
- if not @hash['dir']
63
- return help
64
- else
65
- @dir = @hash['dir']
66
- end
67
-
68
- msg "Clean up existing stats files: app_id_status.json, app_id_stats.csv", Logger::INFO
69
- File.delete("app_id_status.json") if File.exists?("app_id_status.json")
70
- File.delete("app_id_stats.csv") if File.exists?("app_id_stats.csv")
71
-
72
- @api = Scale.new(@@mu_ip, @@mu_admin_user, @@mu_admin_pass)
73
- @api.configure("pattern", @cmd_line_pattern)
74
- @params = {}
75
- @params["dir"] = @dir
76
- @params["hosts"] = @cmd_line_hosts
77
- recursive = (@hash['recursive'].nil?) ? "": "**"
78
- files = Dir.glob(File.join(@dir,recursive,"*.msl"))
79
- if !files.empty?
80
- files.sort.each do | f |
81
- run(f)
82
- output_csv(f)
83
- sleep 2
84
- end
85
- else
86
- msg "no msl files found in #{@dir}", Logger::ERROR
87
- end
88
- @api.release
89
- end
90
-
91
18
  # sets up, executes, and closes a Studio Scale test for one scenario or each scenario (.msl file) found in the specified directory
92
19
  # * argv = command-line arguments
93
20
  # * optional -s scenario file
@@ -606,19 +533,12 @@ class Mu
606
533
  cmds = [
607
534
  "mu cmd_runscale:help",
608
535
  "mu cmd_runscale:run_files -s <scenario>|-d <scenario_directory> --recursive -i <hosts, e.g. a1,dell-9> -p <pattern, e.g. 1-1000:30>",
609
- "mu cmd_runscale:run_file -s <scenario> -i <hosts, e.g. a1,dell-9> -p <pattern, e.g. 1-1000:30>",
610
- "mu cmd_runscale:run_dir -d <scenario_directory>",
611
536
  "mu cmd_runscale:running?"
612
537
  ]
613
538
 
614
539
  max_long_size = helps.inject(0) { |memo, obj| [ obj[:long].size, memo ].max }
615
540
  max_value_size = helps.inject(0) { |memo, obj| [ obj[:value].size, memo ].max }
616
- puts
617
- puts "Usage: mu cmd_runscale:<command> <options>"
618
- puts "\n***WARNING***\nThe following commands will be deprecated in a future release:"
619
- puts "cmd_runscale:run_file, cmd_runscale:run_dir, cmd_appid\n"
620
- puts "Please use 'cmd_runscale:run_files'"
621
- puts
541
+
622
542
  helps.each do |h|
623
543
  puts "%-*s %*s %-*s %s" % [max_long_size, h[:long], 2, h[:short], max_value_size, h[:value], h[:help]]
624
544
  end
@@ -6,7 +6,6 @@ class Help < Command
6
6
  puts "Usage: mu <command>:<option>"
7
7
  helps = [
8
8
  { :cmd => 'mu help', :help => "Display this help" },
9
- { :cmd => 'mu cmd_appid:help', :help => 'Show help on using the appid application for running multi-host msl files at scale'},
10
9
  { :cmd => 'mu cmd_cli:help', :help => 'Show help on using the Mu CLI Api through the command-line' },
11
10
  { :cmd => 'mu cmd_ddt:help', :help => 'Show help on using the Studio Verify Api through the command-line' },
12
11
  { :cmd => 'mu cmd_homepage:help', :help => 'Show help on using the Homepage Api through the command-line' },
@@ -1,7 +1,6 @@
1
1
  # To change this template, choose Tools | Templates
2
2
  # and open the template in the editor.
3
3
  require 'mu/maker'
4
- require 'mu/xmlizable'
5
4
 
6
5
  class Har
7
6
  HTTP_CONTENT_LENGTH_HEADER = 'Content-Length'
@@ -48,10 +47,6 @@ class Har
48
47
 
49
48
  HTTP_CONTENT_SLICE_SIZE = 1024
50
49
 
51
- MSL_ESCAPES = XMLizable::ESCAPES.dup
52
- MSL_ESCAPES['"'.ord] = %q{\"}
53
- MSL_ESCAPES["'".ord] = %q{\'}
54
-
55
50
 
56
51
  attr_reader :har_file
57
52
  attr_accessor :entries,:hosts,:har,:har_hosts
@@ -64,6 +59,7 @@ class Har
64
59
  begin
65
60
  @har = JSON File.read(@har_file)
66
61
  rescue Exception=>e
62
+ puts "There was an error reading the JSON har file, probably a parsing problem"
67
63
  raise e
68
64
  end
69
65
 
@@ -186,8 +182,7 @@ class Har
186
182
  # If this is a Cookie header, try and map the cookie
187
183
  # value to a step variable preceding this step
188
184
  if ('cookie' === header['name'].downcase)
189
- #value = header['value']
190
- value = XMLizable.escape(header['value'], MSL_ESCAPES)
185
+ value = self.escape(header['value'])
191
186
  for j in 0..cookies.length
192
187
  cookie = cookies[j]
193
188
 
@@ -298,7 +293,7 @@ class Har
298
293
  end # end steps.client_send
299
294
 
300
295
  # Skip the server side if the command line option included --endpint
301
- unless @options.endpoint
296
+ #unless @options.endpoint
302
297
  steps.server_receive("sr#{entry_count}", "cs#{entry_count}") do ||
303
298
  #return nil
304
299
  end
@@ -319,7 +314,7 @@ class Har
319
314
  build_payload ss, entry_count, res, scenario
320
315
  end unless @options.ignore_payload
321
316
  end # end server_send
322
- end
317
+ #end
323
318
 
324
319
  # If the endpoint option is chosen only include cs 'client send' values instead of ss 'server send' values
325
320
  receive_side = @options.endpoint ? 'cs' : 'ss'
@@ -419,7 +414,7 @@ class Har
419
414
  end
420
415
  cs_send.literal_no_format("\"");
421
416
  else
422
- cs_send.literal_no_format("\"" + XMLizable.escape(payload, MSL_ESCAPES) + "\"")
417
+ cs_send.literal_no_format("\"" + self.escape(payload) + "\"")
423
418
  end
424
419
 
425
420
 
@@ -446,4 +441,28 @@ class Har
446
441
  not @content_transfer_encoding.to_s == 'binary' and
447
442
  not @mu_content_transfer_encoding.to_s == 'binary'
448
443
  end
444
+
445
+ ESCAPES= Array.new 256 do |i|
446
+ case i
447
+ when 9; "\\t".freeze
448
+ when 13; "\\r".freeze
449
+ when 92; "\\\\".freeze
450
+ when 10; "\\n".freeze
451
+ when 32..126; i.chr.freeze
452
+ else ; ('\x%02x' % i).freeze
453
+ end
454
+ end
455
+ ESCAPES['"'.ord] = %q{\"}
456
+ ESCAPES["'".ord] = %q{\'}
457
+ ESCAPES.freeze
458
+
459
+ # Takes input and a table that maps ascii codes to their representation
460
+ def escape input, escapes=nil
461
+ escapes ||= ESCAPES
462
+ output = []
463
+ input.each_byte do |i|
464
+ output << escapes[i]
465
+ end
466
+ output.join
467
+ end
449
468
  end
@@ -85,10 +85,6 @@ class Maker
85
85
  def escape text
86
86
  text.gsub(/\\/, '\\\\').gsub(/\r/, '\\r').gsub(/\n/, '\\n').gsub(/"/, '\\"')
87
87
  end
88
-
89
- def escape_payload text
90
- text.gsub(/\\/, '\\\\\\').gsub(/\r/, '\\r').gsub(/\n/, '\\n').gsub(/"/, '\\"')
91
- end
92
88
 
93
89
  def attrs kvs = {}
94
90
  return '' if kvs.empty?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mu
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.7.9
4
+ version: 5.7.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-04-08 00:00:00.000000000 -07:00
12
+ date: 2011-04-12 00:00:00.000000000 -07:00
13
13
  default_executable: mu
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
17
- requirement: &3242700 !ruby/object:Gem::Requirement
17
+ requirement: &18971320 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 1.0.0
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *3242700
25
+ version_requirements: *18971320
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: jeweler
28
- requirement: &3241120 !ruby/object:Gem::Requirement
28
+ requirement: &18969320 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 1.5.1
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *3241120
36
+ version_requirements: *18969320
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: rcov
39
- requirement: &3239300 !ruby/object:Gem::Requirement
39
+ requirement: &18968360 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *3239300
47
+ version_requirements: *18968360
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: nokogiri
50
- requirement: &3237320 !ruby/object:Gem::Requirement
50
+ requirement: &18964500 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 1.4.4
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *3237320
58
+ version_requirements: *18964500
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: rest-client
61
- requirement: &3236020 !ruby/object:Gem::Requirement
61
+ requirement: &18963660 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 1.6.1
67
67
  type: :runtime
68
68
  prerelease: false
69
- version_requirements: *3236020
69
+ version_requirements: *18963660
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: mime-types
72
- requirement: &3234040 !ruby/object:Gem::Requirement
72
+ requirement: &18958760 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: '1.16'
78
78
  type: :runtime
79
79
  prerelease: false
80
- version_requirements: *3234040
80
+ version_requirements: *18958760
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: json_pure
83
- requirement: &3228980 !ruby/object:Gem::Requirement
83
+ requirement: &18957600 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,10 +88,10 @@ dependencies:
88
88
  version: 1.4.6
89
89
  type: :runtime
90
90
  prerelease: false
91
- version_requirements: *3228980
91
+ version_requirements: *18957600
92
92
  - !ruby/object:Gem::Dependency
93
93
  name: hexy
94
- requirement: &3225480 !ruby/object:Gem::Requirement
94
+ requirement: &18956640 !ruby/object:Gem::Requirement
95
95
  none: false
96
96
  requirements:
97
97
  - - ! '>='
@@ -99,7 +99,7 @@ dependencies:
99
99
  version: 0.1.1
100
100
  type: :runtime
101
101
  prerelease: false
102
- version_requirements: *3225480
102
+ version_requirements: *18956640
103
103
  description: general purpose mu gem
104
104
  email: bwilkerson@mudynamics.com
105
105
  executables:
@@ -117,7 +117,6 @@ files:
117
117
  - lib/mu/client.rb
118
118
  - lib/mu/command.rb
119
119
  - lib/mu/command/api.rb
120
- - lib/mu/command/cmd_appid.rb
121
120
  - lib/mu/command/cmd_cli.rb
122
121
  - lib/mu/command/cmd_ddt.rb
123
122
  - lib/mu/command/cmd_homepage.rb
@@ -136,9 +135,7 @@ files:
136
135
  - lib/mu/har.rb
137
136
  - lib/mu/helper.rb
138
137
  - lib/mu/http_helper.rb
139
- - lib/mu/libxml.rb
140
138
  - lib/mu/maker.rb
141
- - lib/mu/xmlizable.rb
142
139
  - bin/mu
143
140
  has_rdoc: true
144
141
  homepage: http://www.mudynamics.com
@@ -156,7 +153,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
156
153
  version: '0'
157
154
  segments:
158
155
  - 0
159
- hash: -3112838323153453610
156
+ hash: -973453883911657948
160
157
  required_rubygems_version: !ruby/object:Gem::Requirement
161
158
  none: false
162
159
  requirements:
@@ -1,531 +0,0 @@
1
- # runs Mu Studio multi-host app_id msl files in Studio Scale, in client/server passthrough
2
- # mode, collapsing all hosts in the scenario to two. Runs either a single msl file or
3
- # a directory of msl files, and has command-line options to specify the Mu parameters,
4
- # the interfaces to use, and the pattern in which to run
5
- require 'mu/api/scale'
6
- class Mu
7
- class Command
8
- class Cmd_appid < Command
9
-
10
- attr_accessor :api, :params, :hosts, :addr_indexes, :hash
11
-
12
- # displays command-line help
13
- def cmd_help argv
14
- help
15
- end
16
-
17
- # returns a boolean indicating whether the scale test is running or not
18
- # * argv = command-line arguments
19
- def cmd_running? argv
20
- if @api.nil?
21
- msg "false"
22
- return
23
- end
24
-
25
- status = @api.status
26
- if !status.nil?
27
- if !status["status"].nil?
28
- msg status["status"]["running"]
29
- end
30
- else
31
- msg "false"
32
- end
33
- end
34
-
35
- # runs a single Studio Scale test
36
- # * argv = command-line arguments, requires a scenario (-s) argument
37
- def cmd_run_file argv
38
- puts "\n***WARNING***\nThe following commands will be deprecated in a future release:"
39
- puts "cmd_runscale:run_file, cmd_runscale:run_dir, cmd_appid\n"
40
- puts "Please use 'cmd_runscale:run_files'"
41
- setup argv
42
-
43
- if not @hash['scenario']
44
- raise "*** Error: scenario required, using -s option"
45
- else
46
- scenario = @hash['scenario']
47
- end
48
-
49
- if !File.exists?(scenario)
50
- raise "*** Error: Scenario file #{scenario} was not found"
51
- end
52
-
53
- File.delete("app_id_status.json") if File.exists?("app_id_status.json")
54
- File.delete("app_id_stats.csv") if File.exists?("app_id_stats.csv")
55
-
56
- @api = Scale.new(@@mu_ip, @@mu_admin_user, @@mu_admin_pass)
57
- @api.configure("pattern", @cmd_line_pattern)
58
- @params = {}
59
- @params["msl"] = scenario
60
- @params["hosts"] = @cmd_line_hosts
61
- run(scenario)
62
- @api.release
63
- end
64
-
65
- # runs through a directory of msl files and executes a Studio Scale test for each one
66
- # * argv = command-line arguments, require a directory (-d) argument
67
- # * optional -r argument for recursive directory search (default is a flat directory)
68
- def cmd_run_dir argv
69
- puts "\n***WARNING***\nThe following commands will be deprecated in a future release:"
70
- puts "cmd_runscale:run_file, cmd_runscale:run_dir, cmd_appid\n"
71
- puts "Please use 'cmd_runscale:run_files'"
72
- setup argv
73
-
74
- if not @hash['dir']
75
- raise "*** Error: directory required, using -d option"
76
- else
77
- dir = @hash['dir']
78
- end
79
-
80
- File.delete("app_id_status.json") if File.exists?("app_id_status.json")
81
- File.delete("app_id_stats.csv") if File.exists?("app_id_stats.csv")
82
-
83
- @api = Scale.new(@@mu_ip, @@mu_admin_user, @@mu_admin_pass)
84
- @api.configure("pattern", @cmd_line_pattern)
85
- @params = {}
86
- @params["dir"] = dir
87
- @params["hosts"] = @cmd_line_hosts
88
- Dir.chdir(@params["dir"])
89
- File.delete("app_id_status.json") if File.exists?("app_id_status.json")
90
- if @hash['recursive'].nil?
91
- files = Dir.glob("*.msl")
92
- else
93
- files = Dir.glob("**/*.msl")
94
- end
95
- if !files.empty?
96
- files.sort.each do | f |
97
- run(f)
98
- output_csv(f)
99
- sleep 2
100
- end
101
- else
102
- msg "no msl files found in #{dir}"
103
- end
104
- @api.release
105
- end
106
-
107
- private
108
-
109
- def setup argv
110
- parse_cli argv
111
- @params = {}
112
- @peak_throughput = 0.0
113
-
114
- if @hash['test']
115
- @verify_only = true
116
- else
117
- @verify_only = false
118
- end
119
-
120
- if not @hash['pattern']
121
- @cmd_line_pattern = "{ \"iterations\": 1, \"intervals\": [ {\"iterations\":1, \"end\":100, \"start\":1, \"duration\":20 } ] }"
122
- else
123
- @cmd_line_pattern = @hash['pattern']
124
- end
125
-
126
- if not @hash['interfaces']
127
- @cmd_line_hosts = "b1,b2"
128
- else
129
- @cmd_line_hosts = @hash['interfaces']
130
- end
131
-
132
- if not @hash['testset']
133
- @testset = ""
134
- else
135
- @testset = @hash['testset']
136
- end
137
-
138
- if not @hash['delay']
139
- @delay = 0
140
- else
141
- @delay = @hash['delay'].to_i
142
- end
143
-
144
- if not @hash['no_verify']
145
- @no_verify = false
146
- else
147
- @no_verify = true
148
- end
149
-
150
- end
151
-
152
- def run(msl)
153
- if !File.exists?(msl)
154
- return "file not found: #{msl}"
155
- end
156
-
157
- @api.configure("musl", File.read(msl))
158
-
159
- unless @testset.empty?
160
- if @testset.include?("/") # assume it is the full path in this case
161
- csv_file = @testset
162
- else
163
- csv_file = @params["dir"] + "/" + @testset
164
- end
165
- @api.configure("csv", File.read(csv_file))
166
- end
167
-
168
- set_global_hosts
169
- all_hosts = get_all_hosts_from_musl(msl)
170
- @hosts_config = map_all_hosts_to_json(all_hosts)
171
- @api.configure("hosts", @hosts_config)
172
- @api.configure("delay", @delay)
173
- if @no_verify == false # don't do verify if no_verify==true
174
- msg "verifying #{msl} ..."
175
- response = @api.verify
176
- # sleep 3
177
- v = parse_verify_response(response)
178
- if v.nil?
179
- msg "error in verify"
180
- return
181
- end
182
- if @verify_only
183
- msg v
184
- return
185
- end
186
- end
187
- msg "starting #{msl} ..."
188
- @api.start
189
- start_time = Time.now.to_i
190
- while true
191
- sleep 5
192
- status = @api.status
193
- if !status.nil?
194
- if !status["status"].nil?
195
- if status["status"]["running"] == false
196
- msg "running = #{status["status"]["running"]}", Logger::DEBUG
197
- r = parse_status(status)
198
- dump_status(status, msl)
199
- return
200
- else
201
- r = parse_status(status)
202
- end
203
- else # status['status'].nil? ... no bonafide status was returned
204
- time_now = Time.now.to_i
205
- if time_now - start_time > 20
206
- # puts "\nError: timing out after 20 seconds. Test had failed to start or verify"
207
- break
208
- end
209
- end
210
- end
211
- end
212
- ensure
213
- msg "stopping #{msl} ..."
214
- end
215
-
216
- def set_global_hosts
217
- @hosts = Array.new
218
- @addr_indexes = Array.new
219
- hosts = @params["hosts"]
220
- if !hosts.nil?
221
- p = hosts.split(",")
222
- p.each do | h |
223
- if h.include?("-") # b1-1000,b2-1 to indicate addr_count
224
- q = h.split("-")
225
- @hosts << q[0]
226
- @addr_indexes << q[1]
227
- else # default to the 1st addr index
228
- @hosts << h
229
- @addr_indexes << 1
230
- end
231
- end
232
- else
233
- @hosts = ['b1','b2']
234
- @addr_indexes = [1,1]
235
- end
236
- end
237
-
238
- def dump_status(status, msl)
239
- filename = "app_id_status.json"
240
- f = File.open(filename, "a")
241
- status["filename"] = msl
242
- str = JSON.pretty_generate(status)
243
- f.write(",") if !File.zero?(f) # if appending, we need to insert a comma
244
- f.write(str)
245
- f.close
246
- end
247
-
248
- def output_csv(msl_file)
249
- filename = "app_id_stats.csv"
250
- doc = "#{msl_file},#{@executed},#{@errors.to_i},#{@timeouts.to_i},#{@client_tx_bytes},#{@client_tx_msgs},#{@client_rx_bytes},#{@client_rx_msgs},#{@server_tx_bytes},#{@server_tx_msgs},#{@server_rx_bytes},#{@server_rx_msgs}\n"
251
- File.open(filename, File::RDWR|File::TRUNC|File::CREAT) {|f| f.write(doc) }
252
- end
253
-
254
- # finds all the hosts in the musl file
255
- def get_all_hosts_from_musl(msl)
256
- f = IO.read(msl)
257
- hosts = f.scan(/host_\d+/)
258
- hosts.uniq!
259
- return hosts
260
- end
261
-
262
- # maps host_0 to the client interface
263
- # maps all other hosts to the server interface
264
- def map_all_hosts_to_json(hosts=[])
265
- new_hosts = Array.new
266
- hosts.each_with_index do | h, i |
267
- if i == 0
268
- new_hosts << @hosts[0] + "/*,#{@addr_indexes[0]}"
269
- else
270
- new_hosts << @hosts[1] + "/*,#{@addr_indexes[1]}"
271
- end
272
- end
273
-
274
- hosts_config = {}
275
-
276
- # assign hosts to consecutive string keys, host_0, host_1, etc ...
277
- new_hosts.each_with_index do | h, i |
278
- hosts_config["host_#{i}"] = h # new_hosts[i]
279
- end
280
-
281
- # convert keys to symbols
282
- new_hosts_config = {}
283
- hosts_config.each_key { |k| new_hosts_config[k.to_sym] = hosts_config[k] }
284
-
285
- return new_hosts_config
286
- end
287
-
288
- def parse_verify_response(response)
289
- if response.nil? # || response.empty?
290
- msg "*** error = no response received from /verify ***\n\n"
291
- return nil
292
- end
293
- begin
294
- msg JSON.pretty_generate(response), Logger::DEBUG
295
- if !response["status"].nil?
296
- if response["status"]["error"] == true
297
- @error = response["status"]["error"]
298
- @reason = response["status"]["reason"]
299
- dump_status(response)
300
- msg "*** Error = #{@error}, reason = #{@reason} ***\n\n"
301
- return nil
302
- end
303
- end
304
- msg "*** verify: okay ***", Logger::DEBUG
305
- return "*** verify: okay ***"
306
- rescue
307
- # could nbe json parse error
308
- return nil
309
- end
310
- end
311
-
312
- def parse_status(status)
313
- return nil if status.nil?
314
- msg JSON.pretty_generate(status), Logger::DEBUG
315
- @reported_volume = 0
316
- if !status["status"]["error"].nil?
317
- if status["status"]["error"] == true
318
- @error = status["status"]["error"]
319
- @reason = status["status"]["reason"]
320
- # puts "*** Error = #{@error}, reason = #{@reason} ***\n\n"
321
- return nil
322
- end
323
- end
324
-
325
- @stats_summary = status["status"]["statistics"]["summary"]
326
- @duration = @stats_summary["duration"]
327
- @instances = @stats_summary["instances"]
328
- @total_instances = @instances["total"]
329
- @executed = @instances["executed"]
330
- @timeouts = @instances["timeouts"]
331
- @errors = @instances["errors"]
332
- @asserts_failed = @stats_summary["asserts"]["failed"]
333
- @server = @stats_summary["server"]
334
- @server_tx_bytes = @server["tx"]["bytes"]
335
- @server_tx_msgs = @server["tx"]["msgs"]
336
- @server_rx_bytes = @server["rx"]["bytes"]
337
- @server_rx_msgs = @server["rx"]["msgs"]
338
- @client = @stats_summary["client"]
339
- @client_tx_bytes = @client["tx"]["bytes"]
340
- @client_tx_msgs = @client["tx"]["msgs"]
341
- @client_rx_bytes = @client["rx"]["bytes"]
342
- @client_rx_msgs = @client["rx"]["msgs"]
343
- @scenarios = status["status"]["statistics"]["scenarios"]
344
- @scenarios.each do | scenario |
345
- @reported_volume = @reported_volume + scenario["volume"]
346
- end
347
-
348
- bits1 = (@client_tx_bytes.to_i + @client_rx_bytes.to_i) * 8
349
- dur1 = @duration.to_f
350
- thruput = format_float(2, bits1.to_f / dur1)
351
-
352
- if thruput.to_f > @peak_throughput
353
- @peak_throughput = thruput.to_f
354
- end
355
-
356
- msg ""
357
- msg "duration: #{format_float(2, @duration)}"
358
- msg "concurrency: #{@reported_volume}"
359
- msg "tests/sec: #{format_float(2, @executed.to_f / @duration)}" if @duration.to_i > 0
360
- msg "bits/sec: #{thruput}" if @duration.to_i > 0
361
- msg "passed: #{@executed}"
362
- msg "errors: #{@errors}"
363
- msg "timeouts: #{@timeouts}"
364
- msg "client tx bytes/sec #{format_float(2, @client_tx_bytes.to_f / @duration)}" if @duration.to_i > 0
365
- msg "client tx msgs/sec #{format_float(2, @client_tx_msgs.to_f / @duration)}" if @duration.to_i > 0
366
- msg "client rx bytes/sec #{format_float(2, @client_rx_bytes.to_f / @duration)}" if @duration.to_i > 0
367
- msg "client rx msgs/sec #{format_float(2, @client_rx_msgs.to_f / @duration)}" if @duration.to_i > 0
368
- msg "server tx bytes/sec #{format_float(2, @server_tx_bytes.to_f / @duration)}" if @duration.to_i > 0
369
- msg "server tx msgs/sec #{format_float(2, @server_tx_msgs.to_f / @duration)}" if @duration.to_i > 0
370
- msg "server rx bytes/sec #{format_float(2, @server_rx_bytes.to_f / @duration)}" if @duration.to_i > 0
371
- msg "server rx msgs/sec #{format_float(2, @server_rx_msgs.to_f / @duration)}" if @duration.to_i > 0
372
- msg ""
373
- end
374
-
375
- def parse_cli argv
376
- @hash = Hash.new
377
- while not argv.empty?
378
- break if argv.first[0,1] != '-'
379
-
380
- k = argv.shift
381
-
382
- if [ '-c', '--csv' ].member? k
383
- @hash['testset'] = shift(k, argv)
384
- next
385
- end
386
-
387
- if [ '-d', '--dir' ].member? k
388
- @hash['dir'] = shift(k, argv)
389
- next
390
- end
391
-
392
- if [ '-i', '--interfaces' ].member? k
393
- @hash['interfaces'] = shift(k, argv)
394
- next
395
- end
396
-
397
- if [ '-h', '--help' ].member? k
398
- help
399
- exit
400
- end
401
-
402
- if [ '-l', '--delay' ].member? k
403
- @hash['delay'] = shift(k, argv)
404
- next
405
- end
406
-
407
- if [ '-m', '--mu_string' ].member? k
408
- mu_string = shift(k, argv)
409
- if mu_string =~ /(.+?):(.+?)@(.*)/
410
- @@mu_admin_user = $1
411
- @@mu_admin_pass = $2
412
- @@mu_ip = $3
413
- end
414
- next
415
- end
416
-
417
- if [ '-n', '--no_verify' ].member? k
418
- @hash['no_verify'] = true
419
- next
420
- end
421
-
422
- if [ '-o', '--output'].member? k
423
- $stdout.reopen(shift(k, argv), "w")
424
- next
425
- end
426
-
427
- if [ '-p', '--pattern' ].member? k
428
- patterns = Array.new
429
- pattern_string = shift(k, argv)
430
- pstrings = pattern_string.split(",")
431
- pstrings.each do | p |
432
- if p =~ /(.+?)-(.+?):(.*)/ # e.g. 1-10000:60
433
- start_vol = $1
434
- end_vol = $2
435
- duration = $3
436
- patterns << "{\"iterations\":1, \"end\":#{end_vol}, \"start\":#{start_vol}, \"duration\":#{duration} }"
437
- end
438
- end
439
- ps = "{ \"iterations\": 1, \"intervals\": ["
440
- patterns.each do | p |
441
- ps = ps + p + ","
442
- end
443
- ps = ps[0..ps.length-2] # remove final comma
444
- ps = ps + "] }"
445
- @hash['pattern'] = ps
446
- next
447
- end
448
-
449
- if [ '-r', '--recursive'].member? k
450
- @hash['recursive'] = true
451
- next
452
- end
453
-
454
- if [ '-s', '--scenario' ].member? k
455
- @hash['scenario'] = shift(k, argv)
456
- next
457
- end
458
-
459
- if [ '-t', '--test' ].member? k
460
- @hash['test'] = true
461
- next
462
- end
463
-
464
- if [ '-v', '--verbose' ].member? k
465
- $log.level = Logger::DEBUG
466
- next
467
- end
468
-
469
- raise ArgumentError, "Unknown option #{k}"
470
- end
471
-
472
- hash
473
- end
474
-
475
- def help
476
- helps = [
477
- { :short => '-c', :long => '--csv', :value => '<string>', :help => 'name of the csv testset to run' },
478
- { :short => '-d', :long => '--dir', :value => '<string>', :help => 'directory containing msl files, required for run_dir' },
479
- { :short => '-h', :long => '--help', :value => '', :help => 'help on command line options' },
480
- { :short => '-i', :long => '--interfaces', :value => '<string>', :help => 'comma-separated list of interfaces, e.g. b1,b2 or b1-1000:0,b2 for ip range and offset' },
481
- { :short => '-l', :long => '--delay', :value => '<string>', :help => 'intra-scenario delay value' },
482
- { :short => '-m', :long => '--mu_string', :value => '<string>', :help => 'user, password, mu_ip in the form of admin:admin@10.9.8.7' },
483
- { :short => '-n', :long => '--no_verify', :value => '', :help => 'do not do verify before start' },
484
- { :short => '-o', :long => '--output', :value => '<string>', :help => 'output logging to this file' },
485
- { :short => '-p', :long => '--pattern', :value => '<string>', :help => 'pattern in the form of comma-separated concurrency_start-end:duration strings, e.g. 1-10000:60,10000-1:30. Duration is in seconds' },
486
- { :short => '-r', :long => '--recursive', :value => '', :help => 'for run_dir, recurse through sub-directories' },
487
- { :short => '-s', :long => '--scenario', :value => '<string>', :help => 'msl file, required for run_msl' },
488
- { :short => '-t', :long => '--test', :value => '', :help => 'do verify only' },
489
- { :short => '-v', :long => '--verbose', :value => '', :help => 'set Logger::DEBUG level' }
490
- ]
491
-
492
- cmds = [
493
- "mu cmd_appid:help",
494
- "mu cmd_appid:run_file -s <file>",
495
- "mu cmd_appid:run_dir -d <dir> [-r]",
496
- "mu cmd_appid:running?"
497
- ]
498
-
499
- max_long_size = helps.inject(0) { |memo, obj| [ obj[:long].size, memo ].max }
500
- max_value_size = helps.inject(0) { |memo, obj| [ obj[:value].size, memo ].max }
501
- puts "\n***WARNING***\nThe following commands will be deprecated in a future release:"
502
- puts "cmd_runscale:run_file, cmd_runscale:run_dir, cmd_appid\n"
503
- puts "Please use 'cmd_runscale:run_files'"
504
- puts
505
- puts "Usage: mu cmd_appid:<command> <options>"
506
- puts
507
- helps.each do |h|
508
- puts "%-*s %*s %-*s %s" % [max_long_size, h[:long], 2, h[:short], max_value_size, h[:value], h[:help]]
509
- end
510
- puts
511
- puts "Available Commands"
512
- puts
513
- cmds.each do | c |
514
- puts c
515
- end
516
- puts
517
- puts "Outputs"
518
- puts
519
- puts "app_id_stats.csv"
520
- puts "scenario_name , passed , errors , timeouts,"
521
- puts "client tx bytes/sec , client tx msgs/sec , client rx bytes/sec , client rx msgs/src,"
522
- puts "server tx bytes/sec , server tx msgs/sec , server rx bytes/sec , server rx msgs/src"
523
- puts
524
- puts "app_id_status.json"
525
- puts "contains the last status json object returned from polling, per scenario"
526
- end
527
-
528
- end
529
- end # Command
530
- end # Mu
531
-