rhoconnect 3.0.6 → 3.1.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. data/CHANGELOG.md +9 -0
  2. data/Gemfile +3 -3
  3. data/Gemfile.lock +38 -17
  4. data/Rakefile +0 -10
  5. data/bench/benchapp/Gemfile.lock +1 -0
  6. data/bench/distr_bench/distr_bench_main +94 -27
  7. data/bench/distr_bench/run_test_query_script.sh +22 -18
  8. data/bench/lib/bench/aws_utils.rb +326 -0
  9. data/bench/lib/bench/bench_result_processor.rb +268 -75
  10. data/bench/lib/bench/cli.rb +1 -0
  11. data/bench/lib/bench/distr_runner.rb +102 -0
  12. data/bench/lib/bench/utils.rb +127 -0
  13. data/bench/lib/bench.rb +16 -15
  14. data/bench/prepare_bench +3 -11
  15. data/bench/scripts/test_query_script.rb +6 -7
  16. data/bin/rhoconnect-benchmark +257 -5
  17. data/doc/benchmarks-running.txt +140 -0
  18. data/doc/client-java.txt +236 -0
  19. data/doc/client-objc.txt +41 -1
  20. data/doc/client.txt +12 -0
  21. data/doc/command-line.txt +12 -3
  22. data/doc/cud-conflicts.txt +68 -0
  23. data/doc/deploying.txt +1 -70
  24. data/doc/hosting-rhohub.txt +3 -0
  25. data/doc/install.txt +50 -13
  26. data/doc/java-plugin.txt +217 -177
  27. data/doc/net-plugin.txt +97 -64
  28. data/doc/plugin-intro.txt +4 -2
  29. data/doc/preparing-production.txt +63 -0
  30. data/doc/rhoconnect-redis-stack.txt +252 -0
  31. data/doc/source-adapters.txt +3 -1
  32. data/doc/tutorial.txt +111 -49
  33. data/examples/simple/dump.rdb +0 -0
  34. data/installer/unix-like/rho_connect_install_constants.rb +6 -5
  35. data/installer/unix-like/rho_connect_install_installers.rb +6 -2
  36. data/installer/utils/nix_install_test.rb +2 -0
  37. data/installer/utils/package_upload/auto-repo.rb +136 -0
  38. data/installer/utils/package_upload/repos.rake +6 -3
  39. data/installer/utils/package_upload/s3_upload.rb +11 -6
  40. data/installer/windows/rhosync.nsi +5 -5
  41. data/lib/rhoconnect/client_sync.rb +2 -2
  42. data/lib/rhoconnect/document.rb +12 -0
  43. data/lib/rhoconnect/jobs/source_job.rb +2 -2
  44. data/lib/rhoconnect/predefined_adapters/bench_adapter.rb +61 -0
  45. data/lib/rhoconnect/source.rb +5 -0
  46. data/lib/rhoconnect/source_adapter.rb +10 -1
  47. data/lib/rhoconnect/source_sync.rb +161 -88
  48. data/lib/rhoconnect/store.rb +48 -0
  49. data/lib/rhoconnect/test_methods.rb +6 -6
  50. data/lib/rhoconnect/version.rb +1 -1
  51. data/lib/rhoconnect.rb +25 -2
  52. data/spec/apps/rhotestapp/sources/sample_adapter.rb +29 -0
  53. data/spec/jobs/source_job_spec.rb +5 -5
  54. data/spec/source_adapter_spec.rb +10 -0
  55. data/spec/source_sync_spec.rb +114 -33
  56. data/spec/spec_helper.rb +21 -2
  57. data/spec/store_spec.rb +29 -0
  58. data/spec/support/shared_examples.rb +1 -1
  59. data/spec/test_methods_spec.rb +4 -4
  60. data/tasks/redis.rake +2 -2
  61. metadata +59 -59
  62. data/bench/benchapp/log/passenger.3000.log +0 -1
  63. data/bench/benchapp/log/passenger.9292.log +0 -59
  64. data/bench/benchapp/tmp/pids/passenger.3000.pid.lock +0 -0
  65. data/bench/benchapp/tmp/pids/passenger.9292.pid.lock +0 -0
  66. data/bench/lib/testdata/0-data.txt +0 -0
  67. data/bench/lib/testdata/1-data.txt +0 -0
  68. data/bench/lib/testdata/10-data.txt +0 -15
  69. data/bench/lib/testdata/2-data.txt +0 -3
  70. data/bench/lib/testdata/25-data.txt +0 -39
  71. data/bench/lib/testdata/250-data.txt +0 -353
  72. data/bench/lib/testdata/3-data.txt +0 -4
  73. data/bench/lib/testdata/50-data.txt +0 -70
  74. data/bench/lib/testdata/500-data.txt +0 -711
@@ -0,0 +1,102 @@
1
+ module Bench
2
+ class DistrRunner
3
+
4
+ attr_accessor :start_time, :end_time, :clients_group
5
+ attr_accessor :total_count, :times_count, :times_sum
6
+
7
+ def initialize(clientgroup)
8
+ @clients_group = clientgroup
9
+ end
10
+
11
+ def run(server, sync_key, payload, concurrency, niterations, result_filename=nil)
12
+ # 1) Extract server name
13
+ server ||= 'default'
14
+ if server != 'default'
15
+ Bench.base_url = server
16
+ end
17
+
18
+ # 2) Simulate the payload
19
+ Bench.datasize = payload.to_i
20
+ expected_data = Bench.get_test_data(Bench.datasize)
21
+ Bench.concurrency = concurrency.to_i
22
+ Bench.iterations = niterations.to_i
23
+
24
+ # 3) extract result filename
25
+ Bench.result_filename = result_filename
26
+
27
+ # 4) Set up the server
28
+ begin
29
+ Bench.admin_login = 'rhoadmin'
30
+ Bench.admin_password = ''
31
+ Bench.get_test_server
32
+ Bench.reset_app
33
+ Bench.user_name = "benchuser"
34
+ Bench.password = "password"
35
+ Bench.set_server_state("test_db_storage:application:#{Bench.user_name}",expected_data)
36
+ Bench.reset_refresh_time('RhoInternalBenchmarkAdapter')
37
+
38
+ #6) set the sync key
39
+ @start_time = Time.now + 10.0
40
+ Bench.set_server_state(sync_key, @start_time.to_f.to_s)
41
+ puts "Sync Key #{sync_key} is set to #{@start_time} - waiting for clients now!!!"
42
+
43
+ #7) Start-up all clients
44
+ command="cd /opt/rhoconnect/bin; ruby run_client_benchmark #{server} #{sync_key} #{niterations} 1 #{Bench.datasize} 1>/dev/null"
45
+ ec2_clients = clients_group.client_instances[0,concurrency]
46
+ Bench::AWSUtils.run_stack_ssh_command(ec2_clients, command)
47
+
48
+ #8) Wait until the command is done and save all data to the disk
49
+ sleep(1)
50
+ @total_count = 0
51
+ @start_time = 0.0
52
+ @end_time = 0.0
53
+ @times_sum = 0.0
54
+ @times_count = 0
55
+ process_results
56
+ save_results
57
+
58
+ #9) Clean-up the db
59
+ Bench.reset_app
60
+ rescue Exception => e
61
+ puts "Distributed Bench Runner ERROR !!!"
62
+ puts e.message
63
+ puts e.backtrace.join("\n")
64
+ end
65
+ end
66
+
67
+ def process_results
68
+ finished_data = Bench.get_server_state("bench_statistics_data")
69
+ finished_data.each do |session,session_data|
70
+ puts "Client data for #{session} : startTime (#{session_data['start_time']}), endTime (#{session_data['end_time']})"
71
+ @total_count += session_data['count'].to_i
72
+ @start_time = session_data['start_time'].to_f unless @start_time > 0.0 and session_data['start_time'].to_f >= @start_time
73
+ @end_time = session_data['end_time'].to_f unless session_data['end_time'].to_f <= @end_time
74
+ if not session_data['times'].nil?
75
+ times_data = session_data['times'].split(',')
76
+ @times_count += times_data.size
77
+ times_data.each do |timevalue|
78
+ @times_sum += timevalue.to_f
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ def average_time
85
+ @times_count > 0 ? @times_sum/@times_count : 0.0
86
+ end
87
+
88
+ def save_results
89
+ return if Bench.result_filename.nil?
90
+
91
+ res_hash = YAML.load_file(Bench.result_filename) if File.exist?(Bench.result_filename)
92
+ res_hash ||= {}
93
+ puts "Overall results are : startTime (#{@start_time.to_s}), endTime (#{@end_time.to_s}), count (#{@total_count.to_s}), payload (#{Bench.datasize}), concurrency (#{Bench.concurrency})"
94
+ res_hash[Bench.concurrency.to_s] = (@end_time > 0.0 and @start_time > 0.0) ? [@total_count/(@end_time - @start_time)] : [0.0]
95
+ res_hash[Bench.concurrency.to_s] << average_time
96
+ File.open(Bench.result_filename, 'w' ) do |file|
97
+ file.write res_hash.to_yaml unless res_hash.empty?
98
+ end
99
+ end
100
+
101
+ end
102
+ end
@@ -53,5 +53,132 @@ module Bench
53
53
  0
54
54
  end
55
55
  end
56
+
57
+ def create_subdir(dir)
58
+ begin
59
+ if File.directory? dir
60
+ dir += '_' + Time.now.strftime("%Y_%m_%d_%H_%M_%S")
61
+ end
62
+ Dir.mkdir(dir)
63
+ dir
64
+ rescue
65
+ end
66
+ end
67
+
68
+ def load_settings(file)
69
+ begin
70
+ return YAML.load_file(file)
71
+ rescue Exception => e
72
+ puts "Error opening settings file #{file}: #{e}."
73
+ puts e.backtrace.join("\n")
74
+ raise e
75
+ end
76
+ end
77
+
78
+ def start_rhoconnect_app(options)
79
+ options[:app_started] = false
80
+ path = options[:start_server] || '.'
81
+ if not File.exists?(File.join(path,'settings','settings.yml'))
82
+ puts " Invalid Rhoconnect app path '#{path}' - no app files can be found there"
83
+ return false
84
+ end
85
+ settings = load_settings(File.join(path,'settings','settings.yml'))
86
+ app_url = settings[:production][:syncserver].gsub(/\/$/,'')
87
+
88
+ uri = URI.parse(app_url)
89
+ port = (uri.port and uri.port != 80) ? ":"+uri.port.to_s : ""
90
+ options[:server_url] = "#{uri.scheme}://#{uri.host}#{port}"
91
+
92
+ already_running = check_rc_service(options[:server_url])
93
+ if already_running
94
+ puts " Another Rhoconnect Application is already running at '#{options[:server_url]}'"
95
+ return false
96
+ end
97
+
98
+ # start the app now
99
+ puts "Starting up the Rhoconnect Application at #{options[:server_url]}"
100
+ current_dir = Dir.pwd
101
+ Dir.chdir(path)
102
+ exit_code = system("rake rhoconnect:startbg")
103
+ sleep 1
104
+ Dir.chdir(current_dir)
105
+
106
+ options[:app_started] = check_rc_service(options[:server_url])
107
+ end
108
+
109
+ def stop_rhoconnect_app(options)
110
+ return unless options[:app_started] == true
111
+
112
+ path = options[:start_server] || '.'
113
+ if not File.exists?(File.join(path,'settings','settings.yml'))
114
+ puts " Invalid Rhoconnect app path '#{path}' - no app files can be found there"
115
+ return
116
+ end
117
+ puts "Stopping the Rhoconnect Application at #{options[:server_url]}"
118
+ current_dir = Dir.pwd
119
+ Dir.chdir(path)
120
+ system("rake rhoconnect:stop")
121
+ sleep 1
122
+ Dir.chdir(current_dir)
123
+ end
124
+
125
+ # check_rc_service
126
+ # Makes an HTTP request to check that the rhoconnect app is up and running
127
+ def check_rc_service(server_name)
128
+ success = false
129
+ begin
130
+ request = Net::HTTP.get_response(URI.parse("#{server_name}/console"))
131
+ if request.code == '200'
132
+ success = true
133
+ end
134
+ rescue
135
+ end
136
+ success
137
+ end #check_rc_service
138
+
139
+ # prepare bench results
140
+ def prepare_bench_results_dirs(dir)
141
+ start_dir = Dir.pwd
142
+ Dir.chdir dir
143
+
144
+ # create result directory structure
145
+ ['bench_results'].each do |dir|
146
+ next if dir.nil?
147
+ created_dir = Bench.create_subdir dir
148
+ Dir.chdir created_dir
149
+ end
150
+ result_dir = Dir.pwd
151
+ ['raw_data'].each do |dir|
152
+ Bench.create_subdir dir
153
+ end
154
+
155
+ Dir.chdir start_dir
156
+ result_dir
157
+ end
158
+
159
+ def prepare_bench_results_meta(dir, title, x_keys)
160
+ title ||= "Results"
161
+
162
+ start_dir = Dir.pwd
163
+ Dir.chdir(dir)
164
+
165
+ # 3) create meta.yml file
166
+ meta_hash = {:x_keys => {}, :metrics => {}, :label => title}
167
+ counter = 0
168
+ x_keys = x_keys.sort_by(&Bench.sort_natural_order)
169
+ x_keys.each do |x_key|
170
+ meta_hash[:x_keys][x_key] = counter
171
+ counter += 1
172
+ end
173
+
174
+ meta_hash[:metrics] = {'Throughput' => 0, 'Av.Time' => 1}
175
+
176
+ File.open(File.join(dir,'raw_data','meta.yml'), 'w') do |file|
177
+ file.write meta_hash.to_yaml unless meta_hash.empty?
178
+ end
179
+
180
+ Dir.chdir start_dir
181
+ true
182
+ end
56
183
  end
57
184
  end
data/bench/lib/bench.rb CHANGED
@@ -4,6 +4,7 @@ $:.unshift File.dirname(__FILE__)
4
4
  require 'bench/timer'
5
5
  require 'bench/logging'
6
6
  require 'bench/utils'
7
+ require 'bench/bench_result_processor'
7
8
  require 'bench/result'
8
9
  require 'bench/session'
9
10
  require 'bench/runner'
@@ -53,6 +54,14 @@ module Bench
53
54
  end
54
55
  end
55
56
 
57
+ def get_server_license_info
58
+ token = get_token
59
+ params = {:api_token => token}
60
+ @body = RestClient.post("#{@host}/api/admin/get_license_info",
61
+ params.to_json, :content_type => :json)
62
+ JSON.parse(@body.to_s)
63
+ end
64
+
56
65
  def get_server_state(doc)
57
66
  token = get_token
58
67
  params = {:api_token => token, :doc => doc}
@@ -110,15 +119,18 @@ module Bench
110
119
  def get_test_server(app_name = nil)
111
120
  if @base_url.nil?
112
121
  app_name = 'benchapp' unless app_name
113
- load_settings(File.join(File.dirname(__FILE__),'..',app_name,'settings','settings.yml'))
114
- @base_url = $settings[:development][:syncserver].gsub(/\/$/,'')
122
+ settings = load_settings(File.join(File.dirname(__FILE__),'..',app_name,'settings','settings.yml'))
123
+ @base_url = settings[:development][:syncserver].gsub(/\/$/,'')
115
124
  end
116
125
  uri = URI.parse(@base_url)
117
- port = (uri.port and uri.port != 80) ? ":"+uri.port.to_s : ""
126
+ port = (uri.port and uri.port != 80) ? ":"+uri.port.to_s : ""
127
+ if not uri.scheme
128
+ raise "URI '#{@base_url}' is invalid:\n\t- doesn't have the required scheme part (for example , http://)"
129
+ end
118
130
  @host = "#{uri.scheme}://#{uri.host}#{port}"
119
131
  puts "Test server is #{@host}..."
120
132
  end
121
-
133
+
122
134
  def test(&block)
123
135
  Runner.new.test(@concurrency,@iterations,&block)
124
136
  end
@@ -140,16 +152,5 @@ module Bench
140
152
  end
141
153
  archive
142
154
  end
143
-
144
- # TODO: Share this code with the framework Rho class
145
- def load_settings(file)
146
- begin
147
- $settings = YAML.load_file(file)
148
- rescue Exception => e
149
- puts "Error opening settings file #{file}: #{e}."
150
- puts e.backtrace.join("\n")
151
- raise e
152
- end
153
- end
154
155
  end
155
156
  end
data/bench/prepare_bench CHANGED
@@ -4,27 +4,19 @@ require 'rubygems'
4
4
  $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), 'lib'))
5
5
  require 'bench'
6
6
 
7
- def create_subdir(dir)
8
- begin
9
- Dir.mkdir(dir)
10
- rescue
11
- end
12
- end
13
-
14
7
  # 1) Extract Bench title
15
8
  title = ARGV[0]
16
9
 
17
-
18
10
  # 2) create result directory structure
19
11
  ['bench_results', ARGV[1]].each do |dir|
20
12
  next if dir.nil?
21
- create_subdir dir
13
+ Bench.create_subdir dir
22
14
  Dir.chdir dir
23
15
  end
24
16
  result_dir = Dir.pwd
25
17
 
26
- ['raw_data', 'images'].each do |dir|
27
- create_subdir dir
18
+ ['raw_data'].each do |dir|
19
+ Bench.create_subdir dir
28
20
  end
29
21
 
30
22
  # 3) create meta.yml file
@@ -2,15 +2,14 @@ include BenchHelpers
2
2
  bench_log "Runs simple login,clientcreate,clientregister,sync session and validates response"
3
3
 
4
4
  Bench.config do |config|
5
- config.concurrency ||= 10
5
+ config.concurrency ||= 1
6
6
  config.iterations ||= 10
7
7
  config.datasize ||= 100
8
8
  config.main_marker = 'get-cud'
9
9
  config.user_name = "benchuser"
10
10
  config.password = "password"
11
11
  config.get_test_server
12
- @datasize = Bench.datasize
13
- @expected = Bench.get_test_data(@datasize)
12
+ @datasize = Bench.datasize
14
13
  @all_objects = "[{\"version\":3},{\"token\":\"%s\"},{\"count\":%i},{\"progress_count\":0},{\"total_count\":%i},{\"insert\":""}]"
15
14
  @ack_token = "[{\"version\":3},{\"token\":\"\"},{\"count\":0},{\"progress_count\":%i},{\"total_count\":%i},{}]"
16
15
  @api_token = Bench.get_token
@@ -19,8 +18,9 @@ Bench.config do |config|
19
18
  # if this is not a distributed run - reset the app
20
19
  if not Bench.sync_key
21
20
  config.reset_app
21
+ @expected = Bench.get_test_data(@datasize)
22
22
  config.set_server_state("test_db_storage:application:#{config.user_name}",@expected)
23
- config.reset_refresh_time('MockAdapter')
23
+ config.reset_refresh_time('RhoInternalBenchmarkAdapter')
24
24
  end
25
25
  end
26
26
 
@@ -34,7 +34,6 @@ Bench.synchronize do |config|
34
34
  end
35
35
  sleep(0.010)
36
36
  end
37
- puts " we have here #{cur_time}, #{sync_time}"
38
37
  end
39
38
 
40
39
  Bench.test do |config,session|
@@ -50,11 +49,11 @@ Bench.test do |config,session|
50
49
  end
51
50
 
52
51
  session.get "get-cud", "#{config.base_url}/query" do
53
- {'source_name' => 'MockAdapter', 'client_id' => session.client_id, 'p_size' => @datasize}
52
+ {'source_name' => 'RhoInternalBenchmarkAdapter', 'client_id' => session.client_id, 'p_size' => @datasize}
54
53
  end
55
54
  token = JSON.parse(session.last_result.body)[1]['token']
56
55
  session.get "ack-cud", "#{config.base_url}/query" do
57
- { 'source_name' => 'MockAdapter',
56
+ { 'source_name' => 'RhoInternalBenchmarkAdapter',
58
57
  'client_id' => session.client_id,
59
58
  'token' => token}
60
59
  end
@@ -4,10 +4,262 @@ require 'rubygems'
4
4
  $:.unshift File.join(File.dirname(__FILE__),'..','bench','lib')
5
5
  $:.unshift File.join(File.dirname(__FILE__),'..','bench')
6
6
  require 'bench'
7
+ require 'optparse'
7
8
 
8
- $ARGV.unshift ''
9
- $ARGV.unshift 'rhoadmin'
10
- $ARGV.unshift 'scripts/test_comm_script.rb'
11
- $ARGV.unshift 'start'
9
+ ENV['RACK_ENV']='production'
12
10
 
13
- Bench::Cli.start
11
+ RHOCONNECT_PATH = File.join(File.dirname(__FILE__),'..')
12
+ puts "Rhoconnect-Benchmark Script is started at #{Time.now.to_s}"
13
+
14
+ def parse_options
15
+ begin
16
+ options = {}
17
+ optparse = OptionParser.new do |opts|
18
+ # Set a banner, displayed at the top
19
+ # of the help screen.
20
+ opts.banner = "Usage: rhoconnect-benchmark [options]"
21
+
22
+ options[:server_url] = 'http://localhost:9292'
23
+ opts.on( '-u', '--url URL', 'Use URL as a server for benchmarking' ) do |url|
24
+ options[:server_url] = url
25
+ end
26
+
27
+ options[:start_server] = nil
28
+ opts.on( '-s', '--startserver [APP_PATH]', 'Starts Rhoconnect App Server on localhost and use it for benchmarking' ) do |path|
29
+ options[:start_server] = path || '.'
30
+ end
31
+
32
+ options[:num_clients] = 0
33
+ opts.on( '-C', '--nclients NUMBER', 'Number of concurrent clients to use' ) do |number|
34
+ options[:num_clients] = number
35
+ end
36
+
37
+ options[:num_iterations] = 10
38
+ opts.on( '-R', '--niterations NUMBER', 'Number of iterations to run benchmark test on each client (default - 10)' ) do |number|
39
+ options[:num_iterations] = number
40
+ end
41
+
42
+ options[:payload] = 100
43
+ opts.on( '-p', '--payload NUMBER', 'Simulate payload (number of records), default - 100 recs (~20K)' ) do |number|
44
+ options[:payload] = number
45
+ end
46
+
47
+ options[:max_payload] = 100
48
+ opts.on( '-x', '--mapayload NUMBER', 'Run the benchmarks test varying the payload from 1 to NUMBER' ) do |number|
49
+ options[:max_payload] = number
50
+ options[:payload] = number
51
+ end
52
+
53
+ options[:max_clients] = 1
54
+ opts.on( '-m', '--maxclientloops NUMBER', 'Run the benchmarks test varying the number of clients from 1 to NUMBER' ) do |number|
55
+ options[:max_clients] = number
56
+ options[:num_clients] = number
57
+ end
58
+
59
+ options[:max_payload] = 0
60
+ opts.on( '-x', '--mapayload NUMBER', 'Run the benchmarks test varying the payload from 1 to NUMBER' ) do |number|
61
+ options[:max_payload] = number
62
+ options[:payload] = number
63
+ end
64
+
65
+ options[:save_results] = nil
66
+ options[:title] = 'QUERY'
67
+ opts.on( '-S', '--save [PATH]', 'Save all benchmark results in to the file structure at PATH') do |path|
68
+ options[:save_results] = path || '.'
69
+ options[:title] ||= 'QUERY'
70
+ end
71
+
72
+ opts.on('-t', '--title TITLE', "Name this benchmark's test results with the title TITLE") do |title|
73
+ options[:title] = title
74
+ end
75
+
76
+ opts.on( '-A', '--advanced', 'This convinience option combines -m 10 and -x 500') do
77
+ options[:max_payload] = 500
78
+ options[:payload] = 500
79
+ options[:max_clients] = 10
80
+ options[:num_clients] = 10
81
+ options[:title] ||= "QUERY"
82
+ options[:save_results] = '.'
83
+ end
84
+
85
+ options[:distributed] = nil
86
+ opts.on('-D', '--distributed FNAME', 'Run benchmark test from distributed AWS Cloud Formation using FNAME for options') do |fname|
87
+ options[:max_payload] = 500
88
+ options[:payload] = 500
89
+ options[:max_clients] = 10
90
+ options[:num_clients] = 10
91
+ options[:title] ||= "QUERY"
92
+ options[:save_results] = '.'
93
+ options[:distributed] = fname
94
+ end
95
+
96
+ # This displays the help screen, all programs are
97
+ # assumed to have this option.
98
+ opts.on( '-h', '--help', 'Display rhoconnect-benchmark help information' ) do
99
+ puts opts
100
+ exit 0
101
+ end
102
+ end
103
+
104
+ optparse.parse!
105
+ rescue SystemExit => se
106
+ exit 0
107
+ rescue Exception => e
108
+ puts " Error while parsing the command line options: #{e.message}"
109
+ puts ""
110
+ puts optparse.help
111
+ puts ""
112
+ raise ""
113
+ end
114
+
115
+ options
116
+ end
117
+
118
+ begin
119
+ options = parse_options
120
+ # 1) start up the application - if required
121
+ # NOTE: server URL will be updated
122
+ # from the app's settings
123
+ if options[:start_server] != nil
124
+ if not Bench.start_rhoconnect_app(options)
125
+ puts " Cannot start rhoconnect application at path '#{options[:start_server]}'"
126
+ puts " Exiting..."
127
+ exit 10
128
+ end
129
+ end
130
+
131
+ # 2) Now, parse the server's options
132
+ Bench.base_url = "#{options[:server_url]}/api/application"
133
+ Bench.get_test_server
134
+ Bench.admin_login = 'rhoadmin'
135
+ Bench.admin_password = ''
136
+ #
137
+ if not Bench.check_rc_service(Bench.host)
138
+ puts ""
139
+ puts " In order to run benchmark tests - you need to have the Rhoconnect application"
140
+ puts " up and running on #{options[:server_url]}"
141
+ puts ""
142
+ exit 10
143
+ end
144
+
145
+ # get license info from the server
146
+ rc_license_info = Bench.get_server_license_info
147
+
148
+ if options[:num_clients] == 0
149
+ n_clients = rc_license_info['seats'].to_i / options[:num_iterations]
150
+ if n_clients > 20
151
+ n_clients = 20
152
+ end
153
+ options[:num_clients] = n_clients
154
+ end
155
+ # calculate appropriate numbers for concurrency
156
+ total_num_clients = options[:num_iterations].to_i*options[:num_clients].to_i
157
+ if total_num_clients > rc_license_info['seats']
158
+ puts ""
159
+ puts " In order to run benchmark tests with #{options[:num_clients]} concurrent clients"
160
+ puts " for #{options[:num_iterations]} iterations you need to have a license with at least #{total_num_clients} seats."
161
+ puts " Your application have only #{rc_license_info['seats']} seats available."
162
+ puts " Adjust the number of concurrent clients or number of iterations to fit within the available license."
163
+ puts ""
164
+ exit 10
165
+ end
166
+
167
+ # run test in a loop from 1 to max_clients concurrency
168
+ concurrency_array = []
169
+ if options[:max_clients].to_i > 1
170
+ concurrency_array << 1
171
+ num_loops = 5
172
+ loop_step = (options[:max_clients].to_f - 1.to_f)/(num_loops - 1)
173
+ for i in 1..num_loops-2
174
+ concurrency_array << (1 + i*loop_step + 0.5).to_i
175
+ end
176
+ end
177
+ concurrency_array << options[:num_clients].to_i
178
+ concurrency_array.uniq!
179
+
180
+ # run test in a loop from 1 to max_payload records
181
+ payload_array = []
182
+ if options[:max_payload].to_i > 1
183
+ payload_array << 1
184
+ num_loops = 10
185
+ loop_step = (options[:max_payload].to_f - 1.to_f)/(num_loops - 1)
186
+ for i in 1..num_loops-2
187
+ payload_array << (1 + i*loop_step + 0.5).to_i
188
+ end
189
+ end
190
+ payload_array << options[:payload].to_i
191
+ payload_array.uniq!
192
+
193
+ # load distributed options and create the AWS Cloud Formation Stack
194
+ if options[:distributed] != nil
195
+ puts ""
196
+ puts " Creating Distributed Clients Benchmark"
197
+ puts ""
198
+ require 'bench/aws_utils'
199
+ require 'bench/distr_runner'
200
+ Bench::AWSUtils.init_connection(options[:distributed])
201
+ options[:clients_group] = nil
202
+ options[:clients_group] = Bench::AWSUtils.create_cf_stack
203
+ exit 10 unless options[:clients_group]
204
+ options[:distr_runner] = Bench::DistrRunner.new options[:clients_group]
205
+ end
206
+
207
+ # load the save results options
208
+ result_dir = nil
209
+ if options[:save_results]
210
+ result_dir = Bench.prepare_bench_results_dirs(options[:save_results])
211
+ x_keys = concurrency_array.collect {|t| t.to_s }
212
+ Bench.prepare_bench_results_meta(result_dir, options[:title], x_keys)
213
+ end
214
+
215
+ concurrency_array.each do |concurrency|
216
+ payload_array.each do |payload|
217
+ # initialize default parameters
218
+ bench_args = []
219
+ # Thor's task
220
+ bench_args[0] = 'start'
221
+ # script
222
+ bench_args[1] = 'scripts/test_query_script.rb'
223
+ # admin
224
+ bench_args[2] = 'rhoadmin'
225
+ # admin's password
226
+ bench_args[3] = ''
227
+ # server's URL
228
+ bench_args[4] = Bench.base_url
229
+ # result fname
230
+ result_fname = nil
231
+ result_fname = File.join(result_dir,'raw_data',"bench_result.#{payload}") if result_dir
232
+ bench_args[5] = result_fname
233
+ # concurrency
234
+ bench_args[6] = concurrency
235
+ # number of iterations
236
+ bench_args[7] = options[:num_iterations]
237
+ # datasize
238
+ bench_args[8] = payload
239
+
240
+ # now execute Bench
241
+ if(options[:distributed])
242
+ sync_key = "#{options[:title]}_#{payload}"
243
+ options[:distr_runner].run(Bench.base_url, sync_key, payload, concurrency, options[:num_iterations], result_fname)
244
+ else
245
+ Bench::Cli.start bench_args
246
+ end
247
+ end
248
+ end
249
+
250
+ # once finished - post-process results
251
+ Bench::PostProcessing.execute result_dir
252
+ rescue Exception => e
253
+ puts e.message
254
+ ensure
255
+ if options and options[:app_started] == true
256
+ Bench.stop_rhoconnect_app(options)
257
+ end
258
+
259
+ if options and options[:clients_group]
260
+ Bench::AWSUtils.delete_cf_stack(options[:clients_group].stack_name)
261
+ end
262
+ end
263
+
264
+ puts "Rhoconnect-Benchmark Script is finished at #{Time.now.to_s}"
265
+ puts ""