Description:
added first page load test on localhost
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r314:933be61bc431 - - 4 files changed: 28 inserted, 4 deleted

@@ -0,0 +1,7
1 + How to call
2 + ===========
3 +
4 + Load test for front page:
5 +
6 + ruby runner.rb common_visitors.rb FirstPageViewer 10 -t 10
7 +
@@ -0,0 +1,7
1 + visitor "FirstPageViewer" do
2 + stores_cookies
3 +
4 + site_url "http://localhost:3000"
5 +
6 + get "/"
7 + end
@@ -1,148 +1,157
1 #
1 #
2 # This file is part of a web load testing tool (currently having no name)
2 # This file is part of a web load testing tool (currently having no name)
3 # Copyright (C) 2008 Jittat Fakcharoenphol
3 # Copyright (C) 2008 Jittat Fakcharoenphol
4 #
4 #
5 # This program is free software; you can redistribute it and/or modify
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
8 # (at your option) any later version.
9 #
9 #
10 # This program is distributed in the hope that it will be useful, but
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License for more details.
13 # General Public License for more details.
14 #
14 #
15 # You should have received a copy of the GNU General Public License
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 # 02110-1301, USA.
18 # 02110-1301, USA.
19 #
19 #
20
20
21 require 'visitor_curl_cli'
21 require 'visitor_curl_cli'
22
22
23 + TEMP_DIR = './tmp'
24 +
23 def show_usage
25 def show_usage
24 puts <<USAGE
26 puts <<USAGE
25 using: ruby runner.rb <visitor_file> [<type> <number>] [<type> <number>] ... [options]
27 using: ruby runner.rb <visitor_file> [<type> <number>] [<type> <number>] ... [options]
26 * visitor_file : your visitor definition file, (with or without .rb)
28 * visitor_file : your visitor definition file, (with or without .rb)
27 * type, number : the type and the number of visitors of that type
29 * type, number : the type and the number of visitors of that type
28 * options : any of the following
30 * options : any of the following
29 -t <sec> specify how long (in seconds)
31 -t <sec> specify how long (in seconds)
30 -d dry-run: run, but make no real http requests
32 -d dry-run: run, but make no real http requests
31 USAGE
33 USAGE
32 end
34 end
33
35
36 + def initialize_temp_dir
37 + if !FileTest.exists? TEMP_DIR
38 + Dir.mkdir TEMP_DIR
39 + end
40 + end
41 +
34 def runner(visitor_lists, load_time=60, options={})
42 def runner(visitor_lists, load_time=60, options={})
35 visitors = []
43 visitors = []
36 vcount = 0
44 vcount = 0
37
45
38 visitor_lists.each do |cname, num|
46 visitor_lists.each do |cname, num|
39 begin
47 begin
40 c = Kernel.const_get(cname)
48 c = Kernel.const_get(cname)
41
49
42 num.times do
50 num.times do
43 - visitors[vcount] = c.new(vcount+1)
51 + visitors[vcount] = c.new(vcount+1, TEMP_DIR)
44 visitors[vcount].talkative = true
52 visitors[vcount].talkative = true
45 vcount += 1
53 vcount += 1
46 end
54 end
47 rescue NameError
55 rescue NameError
48 puts "Can't find class #{cname}"
56 puts "Can't find class #{cname}"
49 show_usage
57 show_usage
50 exit(0)
58 exit(0)
51 end
59 end
52 end
60 end
53
61
54 puts "Having #{vcount} visitors"
62 puts "Having #{vcount} visitors"
55
63
56 vthread = []
64 vthread = []
57
65
58 all_start_time = Time.new
66 all_start_time = Time.new
59
67
60 # start all visitors
68 # start all visitors
61 vcount.times do |i|
69 vcount.times do |i|
62 vthread[i] = Thread.new do
70 vthread[i] = Thread.new do
63 visitors[i].run(:forever,options)
71 visitors[i].run(:forever,options)
64 end
72 end
65 end
73 end
66
74
67 # wait for load_time seconds
75 # wait for load_time seconds
68 sleep load_time
76 sleep load_time
69
77
70 visitors.each do |visitor| visitor.stop! end
78 visitors.each do |visitor| visitor.stop! end
71
79
72 all_finish_time = Time.new
80 all_finish_time = Time.new
73
81
74 begin
82 begin
75 # wait for all threads to stop
83 # wait for all threads to stop
76 vcount.times do |i|
84 vcount.times do |i|
77 #puts "Waiting for thread #{i}, #{vthread[i].alive?}"
85 #puts "Waiting for thread #{i}, #{vthread[i].alive?}"
78 vthread[i].join
86 vthread[i].join
79 end
87 end
80
88
81 rescue Interrupt
89 rescue Interrupt
82 # kill all remaining threads
90 # kill all remaining threads
83 vcount.times do |i|
91 vcount.times do |i|
84 vthread[i].kill if vthread[i].alive?
92 vthread[i].kill if vthread[i].alive?
85 end
93 end
86 end
94 end
87
95
88 # clean up
96 # clean up
89 visitors.each do |visitor|
97 visitors.each do |visitor|
90 #puts "Clean up: #{visitor.id}"
98 #puts "Clean up: #{visitor.id}"
91 visitor.cleanup
99 visitor.cleanup
92 end
100 end
93
101
94 #all_finish_time = Time.new
102 #all_finish_time = Time.new
95
103
96 total_req = 0
104 total_req = 0
97
105
98 vcount.times do |i|
106 vcount.times do |i|
99 stat = visitors[i].statistics
107 stat = visitors[i].statistics
100 # puts "TYPE: #{visitors[i].class}"
108 # puts "TYPE: #{visitors[i].class}"
101 # puts "Total requested = #{stat[:num_requested]}"
109 # puts "Total requested = #{stat[:num_requested]}"
102 # puts "Average = #{stat[:avg_request_time]}"
110 # puts "Average = #{stat[:avg_request_time]}"
103 # puts "S.D. = #{stat[:std_dev]}"
111 # puts "S.D. = #{stat[:std_dev]}"
104 total_req += stat[:num_requested]
112 total_req += stat[:num_requested]
105 end
113 end
106
114
107 elapsed_time = all_finish_time - all_start_time
115 elapsed_time = all_finish_time - all_start_time
108
116
109 puts
117 puts
110 puts "Total time = #{elapsed_time} sec."
118 puts "Total time = #{elapsed_time} sec."
111 puts "Total requests = #{total_req}"
119 puts "Total requests = #{total_req}"
112 puts "Trans. per sec = #{total_req/elapsed_time}"
120 puts "Trans. per sec = #{total_req/elapsed_time}"
113 end
121 end
114
122
115 ###########################
123 ###########################
116 # MAIN
124 # MAIN
117 ###########################
125 ###########################
118
126
119 if ARGV.length==0
127 if ARGV.length==0
120 show_usage
128 show_usage
121 exit(0)
129 exit(0)
122 end
130 end
123
131
124 visitor_file = ARGV.shift
132 visitor_file = ARGV.shift
125 require visitor_file
133 require visitor_file
126
134
127 load_time = 60
135 load_time = 60
128 dry_run = false
136 dry_run = false
129
137
130 #build visitor list
138 #build visitor list
131 visitor_list = {}
139 visitor_list = {}
132 while ARGV.length>0
140 while ARGV.length>0
133 key = ARGV.shift
141 key = ARGV.shift
134
142
135 case key
143 case key
136 when '-d'
144 when '-d'
137 dry_run = true
145 dry_run = true
138 when '-t'
146 when '-t'
139 num = ARGV.shift.to_i
147 num = ARGV.shift.to_i
140 load_time = num
148 load_time = num
141 else
149 else
142 num = ARGV.shift.to_i
150 num = ARGV.shift.to_i
143 visitor_list[key] = num
151 visitor_list[key] = num
144 end
152 end
145 end
153 end
146
154
155 + initialize_temp_dir
147 runner visitor_list, load_time, {:dry_run => dry_run}
156 runner visitor_list, load_time, {:dry_run => dry_run}
148
157
@@ -1,147 +1,148
1 #
1 #
2 # This file is part of a web load testing tool (currently having no name)
2 # This file is part of a web load testing tool (currently having no name)
3 # Copyright (C) 2008 Jittat Fakcharoenphol
3 # Copyright (C) 2008 Jittat Fakcharoenphol
4 #
4 #
5 # This program is free software; you can redistribute it and/or modify
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
8 # (at your option) any later version.
9 #
9 #
10 # This program is distributed in the hope that it will be useful, but
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License for more details.
13 # General Public License for more details.
14 #
14 #
15 # You should have received a copy of the GNU General Public License
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 # 02110-1301, USA.
18 # 02110-1301, USA.
19 #
19 #
20
20
21 require 'rubygems'
21 require 'rubygems'
22 require 'uri'
22 require 'uri'
23
23
24 class Visitor
24 class Visitor
25
25
26 attr_accessor :talkative
26 attr_accessor :talkative
27
27
28 class << self
28 class << self
29 attr_accessor :commands
29 attr_accessor :commands
30 attr_accessor :base_url
30 attr_accessor :base_url
31 attr_accessor :cookies_stored
31 attr_accessor :cookies_stored
32 end
32 end
33
33
34 def get_cookie_fname
34 def get_cookie_fname
35 - "cookies.#{@id}"
35 + "#{@base_dir}/cookies.#{@id}"
36 end
36 end
37
37
38 def get_output_fname
38 def get_output_fname
39 - "output.#{@id}"
39 + "#{@base_dir}/output.#{@id}"
40 end
40 end
41
41
42 def id
42 def id
43 @id
43 @id
44 end
44 end
45
45
46 - def initialize(id=0)
46 + def initialize(id=0, base_dir='.')
47 # initialize nil class variable
47 # initialize nil class variable
48 self.class.base_url = "" if (self.class.base_url) == nil
48 self.class.base_url = "" if (self.class.base_url) == nil
49 self.class.cookies_stored = false if self.class.cookies_stored == nil
49 self.class.cookies_stored = false if self.class.cookies_stored == nil
50
50
51 @id = id
51 @id = id
52 + @base_dir = base_dir
52 @cookies_fname = get_cookie_fname
53 @cookies_fname = get_cookie_fname
53 @output_fname = get_output_fname
54 @output_fname = get_output_fname
54 @statistics = Array.new
55 @statistics = Array.new
55 @talkative = false
56 @talkative = false
56
57
57 @stopped = false
58 @stopped = false
58 end
59 end
59
60
60 def cleanup
61 def cleanup
61 trial = 0
62 trial = 0
62 while FileTest.exists?(@cookies_fname)
63 while FileTest.exists?(@cookies_fname)
63 File.delete(@cookies_fname)
64 File.delete(@cookies_fname)
64 if FileTest.exists?(@cookies_fname)
65 if FileTest.exists?(@cookies_fname)
65 # wait until system returns
66 # wait until system returns
66 puts "STILL HERE"
67 puts "STILL HERE"
67 sleep 1
68 sleep 1
68 trial += 1
69 trial += 1
69 break if trial>10
70 break if trial>10
70 end
71 end
71 end
72 end
72
73
73 while FileTest.exists?(@output_fname)
74 while FileTest.exists?(@output_fname)
74 File.delete(@output_fname)
75 File.delete(@output_fname)
75 if FileTest.exists?(@output_fname)
76 if FileTest.exists?(@output_fname)
76 # wait until system returns
77 # wait until system returns
77 sleep 1
78 sleep 1
78 trial += 1
79 trial += 1
79 break if trial>10
80 break if trial>10
80 end
81 end
81 end
82 end
82 end
83 end
83
84
84 def self.site_url(url)
85 def self.site_url(url)
85 self.base_url = url
86 self.base_url = url
86 end
87 end
87
88
88 def self.stores_cookies
89 def self.stores_cookies
89 self.cookies_stored = true
90 self.cookies_stored = true
90 end
91 end
91
92
92 def self.preprocess_param_hash(params)
93 def self.preprocess_param_hash(params)
93 return {} if params==nil
94 return {} if params==nil
94 plist = {}
95 plist = {}
95 params.each do |key,val|
96 params.each do |key,val|
96 if key.is_a? Symbol
97 if key.is_a? Symbol
97 key_s = key.to_s
98 key_s = key.to_s
98 else
99 else
99 key_s = key
100 key_s = key
100 end
101 end
101 plist[key_s] = val
102 plist[key_s] = val
102 end
103 end
103 plist
104 plist
104 end
105 end
105
106
106 def self.get(url,params=nil)
107 def self.get(url,params=nil)
107 self.commands = [] if self.commands==nil
108 self.commands = [] if self.commands==nil
108 self.commands << {
109 self.commands << {
109 :command => :get,
110 :command => :get,
110 :url => url,
111 :url => url,
111 :params => Visitor.preprocess_param_hash(params) }
112 :params => Visitor.preprocess_param_hash(params) }
112 end
113 end
113
114
114 def self.post(url,params=nil,options=nil)
115 def self.post(url,params=nil,options=nil)
115 self.commands = [] if self.commands==nil
116 self.commands = [] if self.commands==nil
116 self.commands << { :command => :post,
117 self.commands << { :command => :post,
117 :url => url,
118 :url => url,
118 :params => Visitor.preprocess_param_hash(params),
119 :params => Visitor.preprocess_param_hash(params),
119 :options => options }
120 :options => options }
120 end
121 end
121
122
122 def substitute_id(st)
123 def substitute_id(st)
123 return st if !(st.is_a? String)
124 return st if !(st.is_a? String)
124 st.gsub(/(()|(\$))\$\{id\}/) do |s|
125 st.gsub(/(()|(\$))\$\{id\}/) do |s|
125 if s=="${id}"
126 if s=="${id}"
126 @id.to_s
127 @id.to_s
127 else
128 else
128 "${id}"
129 "${id}"
129 end
130 end
130 end
131 end
131 end
132 end
132
133
133 def encode_params(params)
134 def encode_params(params)
134 enc = ""
135 enc = ""
135 if params!=nil and params.length!=0
136 if params!=nil and params.length!=0
136 params.each do |key,val|
137 params.each do |key,val|
137 if enc != ""
138 if enc != ""
138 enc += '&'
139 enc += '&'
139 end
140 end
140 val = substitute_id(val)
141 val = substitute_id(val)
141 enc += URI.escape(key) + '=' + URI.escape(val.to_s)
142 enc += URI.escape(key) + '=' + URI.escape(val.to_s)
142 end
143 end
143 end
144 end
144 enc
145 enc
145 end
146 end
146
147
147 def get(url,params)
148 def get(url,params)
You need to be logged in to leave comments. Login now