internethakai 0.2.0
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.
- 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
|