RoadRunner 3.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,3 @@
1
+ == RoadRunner
2
+
3
+ Put appropriate LICENSE for your project here.
data/README ADDED
@@ -0,0 +1,3 @@
1
+ == RoadRunner
2
+
3
+ You should document your project here.
@@ -0,0 +1,46 @@
1
+ #
2
+ # To change this template, choose Tools | Templates
3
+ # and open the template in the editor.
4
+
5
+
6
+ require 'rubygems'
7
+ require 'rake'
8
+ require 'rake/clean'
9
+ require 'rake/gempackagetask'
10
+ require 'rake/rdoctask'
11
+ require 'rake/testtask'
12
+
13
+ spec = Gem::Specification.new do |s|
14
+ s.name = 'RoadRunner'
15
+ s.version = '3.3.1'
16
+ s.has_rdoc = false
17
+ s.extra_rdoc_files = ['README', 'LICENSE']
18
+ s.summary = 'RoadRunner是LoadRunner的Ruby简易实现'
19
+ s.description = s.summary
20
+ s.author = 'CharlesCui'
21
+ s.email = 'zheng.cuizh@gmail.com'
22
+ # s.executables = ['your_executable_here']
23
+ s.files = %w(LICENSE README Rakefile) + Dir.glob("{bin,lib,spec,test}/**/*")
24
+ s.require_path = "lib"
25
+ s.bindir = "bin"
26
+ end
27
+
28
+ Rake::GemPackageTask.new(spec) do |p|
29
+ p.gem_spec = spec
30
+ p.need_tar = true
31
+ p.need_zip = true
32
+ end
33
+
34
+ Rake::RDocTask.new do |rdoc|
35
+ files =['README', 'LICENSE', 'lib/**/*.rb']
36
+ rdoc.rdoc_files.add(files)
37
+ rdoc.main = "README" # page to start on
38
+ rdoc.title = "RoadRunner Docs"
39
+ rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
40
+ rdoc.options << '--line-numbers'
41
+ end
42
+
43
+ Rake::TestTask.new do |t|
44
+ t.test_files = FileList['test/**/*.rb']
45
+ end
46
+
@@ -0,0 +1,13 @@
1
+ #Here is LR Action function
2
+
3
+ module RoadRunnerModule
4
+ def action(&blk)
5
+
6
+ if block_given?
7
+ @actBlk=blk
8
+ else
9
+ raise ArgumentError, "no block"
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,51 @@
1
+ #
2
+
3
+ module RoadRunnerModule
4
+
5
+ module Dbhelper
6
+
7
+ def migrate(tables)
8
+ tables.each do |table|
9
+ case table
10
+ when "scenarios" then
11
+ unless ActiveRecord::Base.connection.tables.include?(table.to_s) then
12
+ ActiveRecord::Base.connection.create_table(table.to_sym) do |t|
13
+ t.column :name, :string, :limit => 256
14
+ t.column :create_at,:string, :limit => 32
15
+ t.column :script, :string,:limit => 10240
16
+ t.column :author, :string, :default => 'Anonymous'
17
+ t.column :author, :tps, :int
18
+ t.column :desc, :string
19
+ end
20
+ end
21
+
22
+ when "transactions" then
23
+ unless ActiveRecord::Base.connection.tables.include?(table.to_s) then
24
+ ActiveRecord::Base.connection.create_table(table.to_sym) do |t|
25
+ t.column :name,:string,:limit => 256
26
+ t.column :scenario_id,:string,:limit => 256
27
+ t.column :success_rate,:string, :limit => 8
28
+ t.column :create_at,:string, :limit => 32
29
+
30
+ end
31
+ end
32
+
33
+ when "records" then
34
+ unless ActiveRecord::Base.connection.tables.include?(table.to_s) then
35
+ ActiveRecord::Base.connection.create_table(table.to_sym) do |t|
36
+ t.column :cost, :string, :limit => 32
37
+ t.column :ts, :string, :limit => 32
38
+ t.column :seq, :int
39
+ t.column :stats,:int
40
+ t.column :transaction_id,:string,:limit => 256
41
+ t.column :create_at,:string, :limit => 32
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ module_function :migrate
49
+ end
50
+
51
+ end
@@ -0,0 +1,13 @@
1
+ #Here is LR End function
2
+
3
+ module RoadRunnerModule
4
+ def ended(&blk)
5
+
6
+ if block_given?
7
+ @endBlk=blk
8
+ else
9
+ raise ArgumentError, "no block"
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ #Here is LR init function
2
+
3
+ module RoadRunnerModule
4
+ def init(&blk)
5
+
6
+ if block_given?
7
+ @initBlk=blk
8
+ else
9
+ raise ArgumentError, "no block"
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ class Scenario < ActiveRecord::Base
2
+ has_many :transactions
3
+ end
4
+ class Transaction < ActiveRecord::Base
5
+ belongs_to :scenario
6
+ has_many :records
7
+ end
8
+ class Record < ActiveRecord::Base
9
+ belongs_to :transaction
10
+ end
@@ -0,0 +1,100 @@
1
+ #After roadRunner.run() executed,
2
+ #execute roadRunner.report() show the Performance report
3
+
4
+ module RoadRunnerModule
5
+
6
+ def report(label='',width=0)
7
+ p " Wait for moment,the report is collecting......"
8
+ content = if @rep
9
+ @succRates = getSuccessRate @transactions
10
+ <<-DOC
11
+ #{"Performance Reports".center(50, '*')}
12
+ #{label.ljust(width)}
13
+ #{Benchmark::Tms::CAPTION}
14
+ #{@rep.format}
15
+ #{'--'*32}
16
+ The Virtual User is #{@users}.
17
+ Total Execute #{@iterations*@users} Action(s).
18
+ Total Cost #{@rep.real} Second(s).
19
+ This Scenario's TPS : #{@tps}.
20
+ The longest action cost #{@longest || 0} seconds.
21
+ #{'Transaction Report'.center(50, '-')}
22
+ #{@transactions.inject("") { |str,k|
23
+ str += "#{k[0].to_s} : count => #{k[1].size} time(s) , cost => #{k[1].inject(0){|c,v|c+=v[:cost].to_f}.to_s[0..3]} sec(s) , success rate => #{@succRates[k[0]]}\n "
24
+ }.gsub(/\n$/,'')}
25
+ #{'--'*32}
26
+ User defined params as below:
27
+ #{@global}
28
+ #{"End of Reports".center(50, '*')}
29
+ DOC
30
+ else
31
+ "None Report before RoadRunner run."
32
+ end
33
+ puts content
34
+ self.log.info content
35
+ end
36
+
37
+ def save_report(opts={:author=>'Anonymous',:script=>""})
38
+
39
+ p " Saving report to database......"
40
+ opts={:author=>'Anonymous',:script=>""}.merge opts
41
+ if @data_write then
42
+ unless opts[:name] then
43
+ self.log.warn "scenario name may be needed."
44
+ require 'uuidtools' unless defined?UUID
45
+ # scenario || UUID.random_create.to_s is for debug
46
+ opts[:name] = opts[:name] || UUID.random_create.to_s
47
+ self.log.info "scenario is created as #{opts[:name]}"
48
+ end
49
+ # => scenario = Scenario.find_or_create_by_name(opts.merge({:create_at=>Time.now})).shift
50
+ scenario = Scenario.find_or_create_by_name(opts.merge({:create_at=>Time.now}))
51
+ scenario.tps+=@iterations*@users/@rep.real
52
+
53
+ # => if opts[:script] is set as <your script>.rb 's path
54
+ # => opts[:script] = __FILE__
55
+ # => then scenario.script will be set.
56
+ if FileTest.exist?(opts[:script]) then
57
+ scenario.script = ""
58
+ IO.foreach(opts[:script]){|x|scenario.script << x}
59
+ end
60
+
61
+ @succRates = @succRates || (getSuccessRate @transactions)
62
+ # k is transaction name ,
63
+ # v is reports in every transaction.
64
+ @transactions.each do |k,v|
65
+ transaction = Transaction.new({:name=>k,:create_at=>Time.now,:success_rate=>@succRates[k]})
66
+ v.each_index do |id|
67
+ transaction.records << Record.new(v[id].merge({:seq=>id,:ts=>v[id][:create_at].to_f-@strat_time.to_f}))
68
+ self.log.debug "v[#{id}] = #{v[id].inspect}"
69
+ end
70
+ scenario.transactions << transaction
71
+ end
72
+ begin
73
+ scenario.save!
74
+ p " Saved OK!"
75
+ rescue =>e
76
+ self.log.error e
77
+ p e
78
+ end
79
+ self.log.info "records has saved in DB."
80
+ else
81
+ p ' Error:You didn\'t connect any database.'
82
+ self.log.error 'You didn\'t connect any database.'
83
+ end
84
+ end
85
+
86
+ def getSuccessRate(transactions)
87
+ result = {}
88
+ transactions.each do |h|
89
+ success,faile = 0,0
90
+ h[1].each do |r|
91
+ r[:stats]==0?success+=1:faile+=1
92
+ end
93
+ result[h[0]]=success.to_f/(success+faile)
94
+ end
95
+ result
96
+ end
97
+
98
+ private :getSuccessRate
99
+
100
+ end
@@ -0,0 +1,113 @@
1
+ # Author : zheng.cuizh@gmail.com
2
+ # RoadRunner named lik LoadRunner which is a industry performance test tool of HP.
3
+ # I'm happy to user LR and Ruby,
4
+ # so i coded the RoadRunner.
5
+ # Using RR,you'll find somethings similar to LR.
6
+
7
+ $:.unshift File.dirname(__FILE__)
8
+ require 'rubygems'
9
+ require 'benchmark'
10
+ require 'logger'
11
+ require 'pp'
12
+
13
+ require 'init'
14
+ require 'action'
15
+ require 'ended'
16
+ require 'run'
17
+ require 'report'
18
+ require 'rrhelper'
19
+
20
+ class RoadRunner
21
+
22
+ include RoadRunnerModule
23
+ attr :iterations, true
24
+ attr :users,true
25
+ attr :global,true
26
+ attr :iterationId
27
+ attr :record
28
+ attr :userId
29
+ attr :mode,true
30
+ attr :log
31
+ attr :tps
32
+ alias_method :g,:global
33
+ alias_method :g=,:global=
34
+
35
+ def initialize(opts={})
36
+ # => DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
37
+ opts = {:out=>"roadrunner_stdout.log",:frequency=>'daily',:size=>1048576,:level=>Logger::ERROR}.merge opts
38
+ @users,@iterations,@longest,@userId,@iterationId=1,1,0,0,0
39
+ @initBlk,@actBlk,@endBlk=proc{},proc{},proc{}
40
+ @global,@transactions={},{}
41
+ @log=Logger.new(opts[:out],opts[:frequency],opts[:size])
42
+ @log.level=opts[:level]
43
+ # => mode : sequence,thread
44
+ @mode='sequence'
45
+
46
+ if block_given? then
47
+ require 'active_record'
48
+ require 'db'
49
+
50
+ session = {}
51
+ _session = yield session
52
+ session = _session if session == {}
53
+
54
+ begin
55
+ ActiveRecord::Base.establish_connection(
56
+ #
57
+ # === session defined in block :
58
+ #
59
+ # :adapter=>session[:adapter],
60
+ # :encoding=>session[:encoding],
61
+ # :database=>session[:database],
62
+ # :username=>session[:username],
63
+ # :password=>session[:password],
64
+ # :host=>session[:host]
65
+ #
66
+ session
67
+ )
68
+ self.log.info "connect db ok."
69
+ rescue =>ex
70
+ self.log.error "adapter:#{session[:adapter]}.connect db faile."
71
+ end
72
+
73
+ default_report_table = %w"scenarios transactions records"
74
+
75
+ unless @data_write = default_report_table.inject(true){|r,t| r = r && ActiveRecord::Base.connection.tables.include?(t)} then
76
+ self.log.warn "table rreports doesn't defined and will be created."
77
+ Dbhelper::migrate default_report_table
78
+ if @data_write = default_report_table.inject(true){|r,t| r = r && ActiveRecord::Base.connection.tables.include?(t)} then
79
+ self.log.info "create table #{default_report_table.inspect} successful."
80
+ else
81
+ self.log.error "create table #{default_report_table.inspect} fail."
82
+ end
83
+ end
84
+ require 'model' unless defined? Scenario
85
+ self.log.debug 'model Rreport is reqruired.'
86
+ end
87
+ end
88
+
89
+ def transaction(name,&blk)
90
+ @transactions[name] || @transactions[name] = []
91
+ status = "AUTO"
92
+ # => Status is the last expression in the action block
93
+ rcost = Benchmark::realtime{status = yield} if block_given?
94
+ # => status's value is:
95
+ # => 0=>success
96
+ # => -1=>faile
97
+ case status
98
+ when false,'false','-1',-1 then status = -1
99
+ else status = 0
100
+ end
101
+ # {:stats=>status,:cost=>rcost,:create_at=>Time.now} is one record
102
+ @transactions[name] << {:stats=>status,:cost=>rcost,:create_at=>Time.now}
103
+ # => the below sentence cost a lot of system resource
104
+ # => if you run for production result,keep it annotated!!!
105
+ # self.log.debug @transactions[name].inspect
106
+ rcost
107
+ end
108
+
109
+ def method_missing(name,*args,&blk)
110
+ self.transaction(name.to_s,&blk)
111
+ end
112
+
113
+ end
@@ -0,0 +1,168 @@
1
+ # Logfile created on Mon May 25 14:25:28 +0800 2009 by /
2
+ connect db ok.
3
+ ***************Performance Reports****************
4
+
5
+ user system total real
6
+
7
+ 43.328000 7.657000 50.985000 ( 75.508000)
8
+
9
+ ----------------------------------------------------------------
10
+ The Virtual User is 10.
11
+ Total Execute 500 Action(s).
12
+ Total Cost 75.5080001354218 Second(s).
13
+ This Scenario's TPS : 6.62181489515366.
14
+ The longest action cost 3.24900007247925 seconds.
15
+ ----------------Transaction Report----------------
16
+ Action : count => 500 time(s) , cost => 73.0 sec(s) , success rate => 1.0
17
+ homepage : count => 500 time(s) , cost => 29.6 sec(s) , success rate => 1.0
18
+ auto : count => 500 time(s) , cost => 37.9 sec(s) , success rate => 1.0
19
+
20
+ ----------------------------------------------------------------
21
+ User defined params as below:
22
+
23
+ ******************End of Reports******************
24
+
25
+ connect db ok.
26
+ connect db ok.
27
+ ***************Performance Reports****************
28
+
29
+ user system total real
30
+
31
+ 11.859000 2.828000 14.687000 ( 21.623000)
32
+
33
+ ----------------------------------------------------------------
34
+ The Virtual User is 10.
35
+ Total Execute 100 Action(s).
36
+ Total Cost 21.6230001449585 Second(s).
37
+ This Scenario's TPS : 4.62470514404152.
38
+ The longest action cost 3.125 seconds.
39
+ ----------------Transaction Report----------------
40
+ Action : count => 100 time(s) , cost => 21.5 sec(s) , success rate => 1.0
41
+ homepage : count => 100 time(s) , cost => 8.67 sec(s) , success rate => 1.0
42
+ auto : count => 100 time(s) , cost => 12.4 sec(s) , success rate => 1.0
43
+
44
+ ----------------------------------------------------------------
45
+ User defined params as below:
46
+
47
+ ******************End of Reports******************
48
+
49
+ I, [2009-05-25T14:38:06.388000 #3748] INFO -- : ***************Performance Reports****************
50
+
51
+ user system total real
52
+
53
+ 14.266000 0.015000 14.281000 ( 14.342000)
54
+
55
+ ----------------------------------------------------------------
56
+ The Virtual User is 10.
57
+ Total Execute 1000 Action(s).
58
+ Total Cost 14.3420000076294 Second(s).
59
+ This Scenario's TPS : 69.7252823503025.
60
+ The longest action cost 0.0320000648498535 seconds.
61
+ ----------------Transaction Report----------------
62
+ Action : count => 1000 time(s) , cost => 5.90 sec(s) , success rate => 1.0
63
+
64
+ ----------------------------------------------------------------
65
+ User defined params as below:
66
+ deep1000pi3140.59265383977
67
+ ******************End of Reports******************
68
+
69
+ I, [2009-05-25T16:57:12.328000 #4264] INFO -- : ***************Performance Reports****************
70
+
71
+ user system total real
72
+
73
+ 14.188000 0.016000 14.204000 ( 14.318000)
74
+
75
+ ----------------------------------------------------------------
76
+ The Virtual User is 10.
77
+ Total Execute 1000 Action(s).
78
+ Total Cost 14.3180000782013 Second(s).
79
+ This Scenario's TPS : 69.8421563443395.
80
+ The longest action cost 0.0320000648498535 seconds.
81
+ ----------------Transaction Report----------------
82
+ Action : count => 1000 time(s) , cost => 5.21 sec(s) , success rate => 1.0
83
+
84
+ ----------------------------------------------------------------
85
+ User defined params as below:
86
+ deep1000pi3140.59265383977
87
+ ******************End of Reports******************
88
+
89
+ I, [2009-05-25T16:59:11.609000 #4884] INFO -- : ***************Performance Reports****************
90
+
91
+ user system total real
92
+
93
+ 14.235000 0.032000 14.267000 ( 14.334000)
94
+
95
+ ----------------------------------------------------------------
96
+ The Virtual User is 10.
97
+ Total Execute 1000 Action(s).
98
+ Total Cost 14.3339998722076 Second(s).
99
+ This Scenario's TPS : 69.7641976360633.
100
+ The longest action cost 1 seconds.
101
+ ----------------Transaction Report----------------
102
+ Action : count => 1000 time(s) , cost => 5.38 sec(s) , success rate => 1.0
103
+
104
+ ----------------------------------------------------------------
105
+ User defined params as below:
106
+ deep1000pi3140.59265383977
107
+ ******************End of Reports******************
108
+
109
+ I, [2009-05-25T17:00:02.113000 #5796] INFO -- : ***************Performance Reports****************
110
+
111
+ user system total real
112
+
113
+ 4.906000 0.000000 4.906000 ( 4.955000)
114
+
115
+ ----------------------------------------------------------------
116
+ The Virtual User is 10.
117
+ Total Execute 1000 Action(s).
118
+ Total Cost 4.95499992370605 Second(s).
119
+ This Scenario's TPS : 201.816350231557.
120
+ The longest action cost 1 seconds.
121
+ ----------------Transaction Report----------------
122
+ Action : count => 1000 time(s) , cost => 4.90 sec(s) , success rate => 0.0
123
+
124
+ ----------------------------------------------------------------
125
+ User defined params as below:
126
+ deep1000pi3140.59265383977
127
+ ******************End of Reports******************
128
+
129
+ I, [2009-05-25T17:00:22.402000 #4628] INFO -- : ***************Performance Reports****************
130
+
131
+ user system total real
132
+
133
+ 4.906000 0.000000 4.906000 ( 4.908000)
134
+
135
+ ----------------------------------------------------------------
136
+ The Virtual User is 10.
137
+ Total Execute 1000 Action(s).
138
+ Total Cost 4.90799999237061 Second(s).
139
+ This Scenario's TPS : 203.748981571818.
140
+ The longest action cost 1 seconds.
141
+ ----------------Transaction Report----------------
142
+ Action : count => 1000 time(s) , cost => 4.86 sec(s) , success rate => 1.0
143
+
144
+ ----------------------------------------------------------------
145
+ User defined params as below:
146
+ deep1000pi3140.59265383977
147
+ ******************End of Reports******************
148
+
149
+ I, [2009-05-25T17:01:05.497000 #5828] INFO -- : ***************Performance Reports****************
150
+
151
+ user system total real
152
+
153
+ 14.297000 0.047000 14.344000 ( 14.381000)
154
+
155
+ ----------------------------------------------------------------
156
+ The Virtual User is 10.
157
+ Total Execute 1000 Action(s).
158
+ Total Cost 14.3810000419617 Second(s).
159
+ This Scenario's TPS : 69.5361933858664.
160
+ The longest action cost 1 seconds.
161
+ ----------------Transaction Report----------------
162
+ Action : count => 1000 time(s) , cost => 5.82 sec(s) , success rate => 1.0
163
+
164
+ ----------------------------------------------------------------
165
+ User defined params as below:
166
+ deep1000pi3140.59265383977
167
+ ******************End of Reports******************
168
+