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.
Files changed (36) hide show
  1. data/CHANGES +53 -0
  2. data/README +177 -0
  3. data/bin/hakaigen +10 -0
  4. data/bin/internethakai +9 -0
  5. data/internethakai.gemspec +27 -0
  6. data/lib/internethakai.rb +26 -0
  7. data/lib/internethakai.rb.~1~ +25 -0
  8. data/lib/internethakai/action.rb +403 -0
  9. data/lib/internethakai/client_handler.rb +175 -0
  10. data/lib/internethakai/client_queue.rb +27 -0
  11. data/lib/internethakai/concurrency_manager.rb +333 -0
  12. data/lib/internethakai/concurrency_manager.rb.~1~ +331 -0
  13. data/lib/internethakai/core.rb +146 -0
  14. data/lib/internethakai/executor.rb +129 -0
  15. data/lib/internethakai/generator.rb +32 -0
  16. data/lib/internethakai/hakairev.rb +119 -0
  17. data/lib/internethakai/hakairev/executor.rb +43 -0
  18. data/lib/internethakai/hakairev/http_client.rb +362 -0
  19. data/lib/internethakai/hakairev/http_client.rb.~1~ +371 -0
  20. data/lib/internethakai/hakairev/monkey.rb +70 -0
  21. data/lib/internethakai/hakairev/revpipe.rb +39 -0
  22. data/lib/internethakai/hakairev/task.rb +39 -0
  23. data/lib/internethakai/hakairev/time_register.rb +116 -0
  24. data/lib/internethakai/hakairev/timer_factory.rb +38 -0
  25. data/lib/internethakai/http_client.rb +120 -0
  26. data/lib/internethakai/logger.rb +52 -0
  27. data/lib/internethakai/main.rb +90 -0
  28. data/lib/internethakai/reporter.rb +143 -0
  29. data/lib/internethakai/response.rb +65 -0
  30. data/lib/internethakai/scenario.rb +98 -0
  31. data/lib/internethakai/scenario.tmpl +58 -0
  32. data/lib/internethakai/scenario_builder.rb +183 -0
  33. data/lib/internethakai/scenario_handler.rb +91 -0
  34. data/lib/internethakai/time_register.rb +53 -0
  35. data/lib/internethakai/util.rb +130 -0
  36. 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