internethakai 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +53 -0
- data/README +177 -0
- data/bin/hakaigen +10 -0
- data/bin/internethakai +9 -0
- data/internethakai.gemspec +27 -0
- data/lib/internethakai.rb +26 -0
- data/lib/internethakai.rb.~1~ +25 -0
- data/lib/internethakai/action.rb +403 -0
- data/lib/internethakai/client_handler.rb +175 -0
- data/lib/internethakai/client_queue.rb +27 -0
- data/lib/internethakai/concurrency_manager.rb +333 -0
- data/lib/internethakai/concurrency_manager.rb.~1~ +331 -0
- data/lib/internethakai/core.rb +146 -0
- data/lib/internethakai/executor.rb +129 -0
- data/lib/internethakai/generator.rb +32 -0
- data/lib/internethakai/hakairev.rb +119 -0
- data/lib/internethakai/hakairev/executor.rb +43 -0
- data/lib/internethakai/hakairev/http_client.rb +362 -0
- data/lib/internethakai/hakairev/http_client.rb.~1~ +371 -0
- data/lib/internethakai/hakairev/monkey.rb +70 -0
- data/lib/internethakai/hakairev/revpipe.rb +39 -0
- data/lib/internethakai/hakairev/task.rb +39 -0
- data/lib/internethakai/hakairev/time_register.rb +116 -0
- data/lib/internethakai/hakairev/timer_factory.rb +38 -0
- data/lib/internethakai/http_client.rb +120 -0
- data/lib/internethakai/logger.rb +52 -0
- data/lib/internethakai/main.rb +90 -0
- data/lib/internethakai/reporter.rb +143 -0
- data/lib/internethakai/response.rb +65 -0
- data/lib/internethakai/scenario.rb +98 -0
- data/lib/internethakai/scenario.tmpl +58 -0
- data/lib/internethakai/scenario_builder.rb +183 -0
- data/lib/internethakai/scenario_handler.rb +91 -0
- data/lib/internethakai/time_register.rb +53 -0
- data/lib/internethakai/util.rb +130 -0
- metadata +134 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
module InternetHakai
|
2
|
+
class TaskQueue < BaseHandler
|
3
|
+
UNIQUE_BY_THREAD = false
|
4
|
+
require 'thread'
|
5
|
+
def initialize id
|
6
|
+
super(id)
|
7
|
+
@queue = []
|
8
|
+
#@queue = Queue::new
|
9
|
+
#@watcher = Rev::AsyncWatcher::new
|
10
|
+
#this = self
|
11
|
+
#task = lambda{
|
12
|
+
# this.run
|
13
|
+
#}
|
14
|
+
#@watcher.on_signal(&task)
|
15
|
+
end
|
16
|
+
def get
|
17
|
+
@queue.shift
|
18
|
+
#@queue.deq
|
19
|
+
end
|
20
|
+
def empty?
|
21
|
+
@queue.empty?
|
22
|
+
end
|
23
|
+
def add v
|
24
|
+
#puts "add"
|
25
|
+
@queue.push(v)
|
26
|
+
#@queue.enq(v)
|
27
|
+
#@watcher.signal
|
28
|
+
end
|
29
|
+
def clear
|
30
|
+
while !@queue.empty?
|
31
|
+
run
|
32
|
+
end
|
33
|
+
end
|
34
|
+
def run
|
35
|
+
task, args = @queue.shift
|
36
|
+
task.call(*args) if task
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module InternetHakai
|
2
|
+
class RevTimeRegister < TimeRegister
|
3
|
+
def next_record
|
4
|
+
@reports << @report
|
5
|
+
@report = ResponseRecord::new
|
6
|
+
@cnt = 0
|
7
|
+
end
|
8
|
+
def get_record
|
9
|
+
exec
|
10
|
+
return @report if @reports.empty?
|
11
|
+
next_record
|
12
|
+
@reports.each do |r|
|
13
|
+
@report += r
|
14
|
+
end
|
15
|
+
@reports = []
|
16
|
+
@report
|
17
|
+
end
|
18
|
+
def on_create
|
19
|
+
@report = ResponseRecord::new
|
20
|
+
@reports = []
|
21
|
+
@stack = []
|
22
|
+
@cnt = 0
|
23
|
+
end
|
24
|
+
def exec
|
25
|
+
@stack.each do |arg|
|
26
|
+
do_regist(*arg)
|
27
|
+
end
|
28
|
+
@stack = []
|
29
|
+
@cnt += 1
|
30
|
+
next_record if @cnt == 10
|
31
|
+
end
|
32
|
+
end
|
33
|
+
class PipeTimeRegister < TimeRegister
|
34
|
+
def on_create
|
35
|
+
super
|
36
|
+
@wpipe = TimeRegistProcess::wpipe
|
37
|
+
end
|
38
|
+
def get_record
|
39
|
+
return @data if @data
|
40
|
+
@wpipe.write("get\n")
|
41
|
+
io = TimeRegistProcess::rpipe
|
42
|
+
@data = Marshal::load(io)
|
43
|
+
end
|
44
|
+
attr_accessor :wpipe
|
45
|
+
def do_regist name, time, response, error
|
46
|
+
if response.nil?
|
47
|
+
status = 0; size = 0
|
48
|
+
else
|
49
|
+
status = response.status; size = response.body.size
|
50
|
+
end
|
51
|
+
@wpipe.write(['regist', name, time, status, size, error].join("\t")+"\n")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
class TimeRegistProcess
|
55
|
+
def self::wpipe
|
56
|
+
@@wpipe
|
57
|
+
end
|
58
|
+
def self::rpipe
|
59
|
+
@@rpipe
|
60
|
+
end
|
61
|
+
def self::run
|
62
|
+
@@alive = true
|
63
|
+
@@rpipe, w = ::IO::pipe
|
64
|
+
r, @@wpipe = ::IO::pipe
|
65
|
+
@@wpipe = Rev::IO::new(@@wpipe)
|
66
|
+
@@wpipe.attach(Rev::Loop::default)
|
67
|
+
fork do
|
68
|
+
revio = RWatcher::new(r)
|
69
|
+
revio.attach(Rev::Loop::default)
|
70
|
+
self::new(revio, w)
|
71
|
+
Rev::Loop::default.run
|
72
|
+
end
|
73
|
+
end
|
74
|
+
def initialize(rpipe, wpipe)
|
75
|
+
@report = ResponseRecord::new
|
76
|
+
@rpipe = rpipe
|
77
|
+
@wpipe = wpipe
|
78
|
+
@rpipe.on_read(&method(:on_read))
|
79
|
+
end
|
80
|
+
def on_read str
|
81
|
+
str.each_line do |l|
|
82
|
+
parse l
|
83
|
+
end
|
84
|
+
end
|
85
|
+
def parse line
|
86
|
+
method, name, time, status, size, err = line.chomp.split("\t")
|
87
|
+
case method
|
88
|
+
when 'regist'
|
89
|
+
regist name, time.to_f, status, size.to_i, err.to_i
|
90
|
+
when 'get'
|
91
|
+
Marshal::dump(@report, @wpipe)
|
92
|
+
Rev::Loop::default.stop
|
93
|
+
end
|
94
|
+
end
|
95
|
+
def regist name, time, status, size, err
|
96
|
+
time = time.to_f
|
97
|
+
v = @report[name]
|
98
|
+
v[:size] += size
|
99
|
+
|
100
|
+
if v[:min].nil? and time != 0
|
101
|
+
v[:min] = time
|
102
|
+
v[:max] = time
|
103
|
+
elsif time != 0
|
104
|
+
v[:min] = v[:min] < time ? v[:min] : time
|
105
|
+
end
|
106
|
+
if time != 0
|
107
|
+
v[:max] = v[:max] > time ? v[:max] : time
|
108
|
+
end
|
109
|
+
v[:totaltime] += time ## 総合時間
|
110
|
+
v[:accesscount] += 1 if time > 0
|
111
|
+
v[:errorcount] += err
|
112
|
+
v["status:#{status}"] = v["status:#{status}"].to_i + 1 unless status!=0
|
113
|
+
v["time:#{((time*1000).to_i/100)*100}"] = v["time:#{((time*1000).to_i/100)*100}"].to_i + 1
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module InternetHakai
|
2
|
+
class TimerFactory
|
3
|
+
@@instance = nil
|
4
|
+
def self::instance
|
5
|
+
@@instance
|
6
|
+
end
|
7
|
+
def initialize timeout, concurrency, loop
|
8
|
+
@timeout = timeout
|
9
|
+
@concurrency = concurrency
|
10
|
+
@loop = loop
|
11
|
+
@stack = []
|
12
|
+
@@instance = self
|
13
|
+
prepare
|
14
|
+
end
|
15
|
+
def prepare
|
16
|
+
1.upto(@concurrency) do
|
17
|
+
@stack << create
|
18
|
+
end
|
19
|
+
end
|
20
|
+
def create
|
21
|
+
timer = Rev::TimerWatcher::new(@timeout, true)
|
22
|
+
timer.attach(@loop)
|
23
|
+
timer.disable
|
24
|
+
return timer
|
25
|
+
end
|
26
|
+
def collect timer
|
27
|
+
return if timer.nil?
|
28
|
+
timer.disable if timer.enabled?
|
29
|
+
@stack.push(timer)
|
30
|
+
end
|
31
|
+
def get
|
32
|
+
timer = @stack.shift || create
|
33
|
+
timer.reset
|
34
|
+
timer.enable unless timer.enabled?
|
35
|
+
return timer
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module InternetHakai
|
2
|
+
module HttpClientIf
|
3
|
+
def release
|
4
|
+
end
|
5
|
+
def reconnect
|
6
|
+
end
|
7
|
+
def set_callback(on_complete, on_error)
|
8
|
+
end
|
9
|
+
def set_cookie cookie
|
10
|
+
end
|
11
|
+
end
|
12
|
+
class HttpClient
|
13
|
+
include HttpClientIf
|
14
|
+
require 'net/http'
|
15
|
+
require 'uri'
|
16
|
+
attr_reader :requestURL, :response, :busy
|
17
|
+
attr_accessor :timeout
|
18
|
+
def self::create host, port
|
19
|
+
o = self::new(host,port)
|
20
|
+
o
|
21
|
+
end
|
22
|
+
# コンストラクタ
|
23
|
+
def initialize(host, port)
|
24
|
+
@host = host
|
25
|
+
@port = port
|
26
|
+
@on_error = nil
|
27
|
+
@on_success = nil
|
28
|
+
free()
|
29
|
+
@header = Hash::new
|
30
|
+
Net::HTTP.version_1_2
|
31
|
+
if ENV["HTTP_PROXY"]
|
32
|
+
@proxy = ENV["HTTP_PROXY"].split(':')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
# コンストラクタ/デストラクタヘルパ
|
36
|
+
def free()
|
37
|
+
@client = nil
|
38
|
+
@ca_path = nil
|
39
|
+
@requestURL = nil
|
40
|
+
@response = nil
|
41
|
+
@timeout = nil
|
42
|
+
@header = nil
|
43
|
+
@proxy = nil
|
44
|
+
@post_string = nil
|
45
|
+
@response_time = nil
|
46
|
+
@busy = false
|
47
|
+
end
|
48
|
+
def set_headers header
|
49
|
+
@header = header
|
50
|
+
end
|
51
|
+
def set_cookie cookie
|
52
|
+
@cookie = cookie
|
53
|
+
end
|
54
|
+
def set_header key, value
|
55
|
+
@header[key] = value
|
56
|
+
end
|
57
|
+
def has_callback
|
58
|
+
!@on_success.nil? and !@on_error.nil?
|
59
|
+
end
|
60
|
+
def set_callback on_success, on_error
|
61
|
+
@on_success = on_success
|
62
|
+
@on_error = on_error
|
63
|
+
end
|
64
|
+
def encode_cookie req
|
65
|
+
return unless @cookie
|
66
|
+
req['Cookie'] = @cookie.map{|k,v|
|
67
|
+
"#{k}=#{v}"
|
68
|
+
}.join(';')
|
69
|
+
end
|
70
|
+
def request_send method, path, body = nil
|
71
|
+
if method == GET
|
72
|
+
req = Net::HTTP::Get::new(path, @header)
|
73
|
+
elsif method == POST
|
74
|
+
req = Net::HTTP::Post::new(path, @header)
|
75
|
+
if body
|
76
|
+
@post_string = body
|
77
|
+
end
|
78
|
+
else
|
79
|
+
raise 'invalid method'
|
80
|
+
end
|
81
|
+
encode_cookie(req)
|
82
|
+
begin
|
83
|
+
response = nil
|
84
|
+
@busy = true
|
85
|
+
if @proxy
|
86
|
+
Net::HTTP::Proxy(@proxy[0], @proxy[1]).start(@host, @port) do |http|
|
87
|
+
http.read_timeout = @timeout
|
88
|
+
@starttime = Time::now
|
89
|
+
response = http.request(req, @post_string)
|
90
|
+
@response_time = Time::now - @starttime
|
91
|
+
end
|
92
|
+
else
|
93
|
+
Net::HTTP.start(@host, @port) do |http|
|
94
|
+
http.read_timeout = @timeout
|
95
|
+
#puts "send: #{object_id}"
|
96
|
+
@starttime = Time::now
|
97
|
+
response = http.request(req, @post_string)
|
98
|
+
@response_time = Time::now - @starttime
|
99
|
+
end
|
100
|
+
end
|
101
|
+
$REQUEST_COUNT += 1
|
102
|
+
rescue Exception => err
|
103
|
+
@on_error.call(err) if @on_error
|
104
|
+
@busy = false
|
105
|
+
return
|
106
|
+
end
|
107
|
+
if response.nil?
|
108
|
+
@response = nil
|
109
|
+
else
|
110
|
+
@response = ResponseObject::create_from_nethttp(response)
|
111
|
+
end
|
112
|
+
#puts "starttime: #{@starttime.usec} : #{object_id}"
|
113
|
+
#puts "restime: #{@response_time} : #{object_id}"
|
114
|
+
@response.time = @response_time
|
115
|
+
@on_success.call(@response) if @on_success
|
116
|
+
@busy = false
|
117
|
+
@response
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module InternetHakai
|
2
|
+
# = ロガー
|
3
|
+
class Logger < BaseHandler
|
4
|
+
UNIQUE_BY_THREAD = false
|
5
|
+
def init(config)
|
6
|
+
@config = config
|
7
|
+
level = @config['log_level']
|
8
|
+
if level <= 3
|
9
|
+
def debugverbose text
|
10
|
+
end
|
11
|
+
end
|
12
|
+
if level <= 2
|
13
|
+
def debug text
|
14
|
+
end
|
15
|
+
end
|
16
|
+
if level == 1
|
17
|
+
def emerg text
|
18
|
+
end
|
19
|
+
end
|
20
|
+
@level = level
|
21
|
+
end
|
22
|
+
# 出力ログレベルより小さいレベルの場合に出力
|
23
|
+
def run text, level = 3
|
24
|
+
case level
|
25
|
+
when 4
|
26
|
+
debugverbose text
|
27
|
+
when 3
|
28
|
+
debug text
|
29
|
+
when 2
|
30
|
+
emerg text
|
31
|
+
when 1
|
32
|
+
crit text
|
33
|
+
end
|
34
|
+
end
|
35
|
+
def crit text
|
36
|
+
print text
|
37
|
+
STDOUT.flush
|
38
|
+
end
|
39
|
+
def emerg text
|
40
|
+
print text
|
41
|
+
STDOUT.flush
|
42
|
+
end
|
43
|
+
def debug text
|
44
|
+
print Util::recover_encoding(text, @config)
|
45
|
+
STDOUT.flush
|
46
|
+
end
|
47
|
+
def debugverbose text
|
48
|
+
print Util::recover_encoding(text, @config)
|
49
|
+
STDOUT.flush
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module InternetHakai
|
2
|
+
class Main
|
3
|
+
require 'optparse'
|
4
|
+
def load_config configpath, basepath = nil, args = nil
|
5
|
+
args ||= {}
|
6
|
+
@basepath = basepath || File::dirname(configpath)
|
7
|
+
@scenario_builder = ScenarioBuilder::new(nil)
|
8
|
+
@scenario_builder.load(configpath)
|
9
|
+
@scenario_handler = BaseHandler::get_handler("ScenarioHandler")
|
10
|
+
@config = @scenario_builder.get_config
|
11
|
+
BaseHandler::set_config(@config)
|
12
|
+
@scenario_handler.init(@config)
|
13
|
+
|
14
|
+
reporter = BaseHandler::get_handler(@config["reporter"])
|
15
|
+
if(@config["log_dir"])
|
16
|
+
@basepath = @config["log_dir"]
|
17
|
+
end
|
18
|
+
starttime = Time::now
|
19
|
+
@starttime = starttime
|
20
|
+
start = starttime.strftime( '%Y%m%d_%H%M%S' )
|
21
|
+
reporter.set_dir(@basepath)
|
22
|
+
reporter.init_filename(start)
|
23
|
+
@config['loop'] = args[:loop] if args.has_key? :loop
|
24
|
+
@config['max_request'] = args[:max_request] if args.has_key? :max_request
|
25
|
+
@config['max_scenario'] = args[:concurrency] if args.has_key? :concurrency
|
26
|
+
if @test
|
27
|
+
@config['loop'] = 1
|
28
|
+
@config['max_request'] = 1
|
29
|
+
@config['concurrency'] = 1
|
30
|
+
@config['max_scenario'] = 1
|
31
|
+
@config.delete('fork')
|
32
|
+
@config.delete('max_process')
|
33
|
+
@config['max_request_show'] = 1
|
34
|
+
@config['max_scenario_show'] = 1
|
35
|
+
@config['log_level'] = 3
|
36
|
+
end
|
37
|
+
|
38
|
+
@report_path = reporter.get_filename
|
39
|
+
@logger = BaseHandler::get_handler(@config["logger"])
|
40
|
+
@logger.init(@config)
|
41
|
+
@logger.run(start + "\n", 2)
|
42
|
+
@logger.run("Rev Mode\n", 2) if @config['rev']
|
43
|
+
@logger.run("Target domain = #{@config['domain']}\n", 2)
|
44
|
+
@logger.run("Loop: #{@config['loop']}\n", 2)
|
45
|
+
@logger.run("Request Concurrency: #{@config['max_request_show']}\n", 2)
|
46
|
+
@logger.run("Scenario Concurrency: #{@config['max_scenario_show']}\n", 2)
|
47
|
+
end
|
48
|
+
def main config=nil
|
49
|
+
#引数か、同じディレクトリの「scenario.yml」を読み込みます。
|
50
|
+
if config.nil?
|
51
|
+
config = ARGV[0]
|
52
|
+
end
|
53
|
+
unless config
|
54
|
+
puts "Usage: #{File::basename($0)} SCENARIO"
|
55
|
+
exit
|
56
|
+
end
|
57
|
+
args = {}
|
58
|
+
@test = false
|
59
|
+
opts = OptionParser.new("Usage: #{File::basename($0)} SCENARIO")
|
60
|
+
opts.on("-v", "--version", "show version") do
|
61
|
+
puts "%s %s" %[File.basename($0), InternetHakai::VERSION]
|
62
|
+
puts "ruby %s" % RUBY_VERSION
|
63
|
+
exit
|
64
|
+
end
|
65
|
+
opts.on("--test", "exec in testmode") do
|
66
|
+
@test = true
|
67
|
+
end
|
68
|
+
opts.on('-l', '--loop' 'loop') do |loop|
|
69
|
+
args[:loop] = loop
|
70
|
+
end
|
71
|
+
opts.on('-s', '--max-scenario', 'max-scenario') do |conc|
|
72
|
+
args[:concurrency] = conc
|
73
|
+
end
|
74
|
+
opts.on('-r', '--max-request', 'max-request') do |mr|
|
75
|
+
args[:max_request] = mr
|
76
|
+
end
|
77
|
+
opts.on_tail("-h", "--help", "show this message") do
|
78
|
+
puts opts
|
79
|
+
exit
|
80
|
+
end
|
81
|
+
opts.version = InternetHakai::VERSION
|
82
|
+
opts.parse!(ARGV)
|
83
|
+
|
84
|
+
load_config config, nil, args
|
85
|
+
|
86
|
+
@test = InternetHakai::ConcurrencyManager::new
|
87
|
+
@test.run(@config, @basepath, @starttime)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|