hatetepe 0.4.1 → 0.5.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/parallel_requests.rb +32 -0
- data/hatetepe.gemspec +3 -4
- data/lib/hatetepe/builder.rb +1 -0
- data/lib/hatetepe/cli.rb +11 -20
- data/lib/hatetepe/client.rb +210 -181
- data/lib/hatetepe/connection.rb +31 -12
- data/lib/hatetepe/server/keep_alive.rb +15 -53
- data/lib/hatetepe/server/pipeline.rb +14 -18
- data/lib/hatetepe/server/rack_app.rb +39 -0
- data/lib/hatetepe/server.rb +60 -108
- data/lib/hatetepe/version.rb +1 -1
- data/lib/rack/handler/hatetepe.rb +2 -0
- data/spec/integration/cli/start_spec.rb +84 -92
- data/spec/integration/client/keep_alive_spec.rb +5 -56
- data/spec/integration/client/timeout_spec.rb +93 -0
- data/spec/integration/server/keep_alive_spec.rb +8 -80
- data/spec/integration/server/timeout_spec.rb +45 -0
- data/spec/spec_helper.rb +7 -59
- data/spec/unit/client_spec.rb +68 -363
- data/spec/unit/connection_spec.rb +5 -7
- data/spec/unit/server_spec.rb +108 -338
- metadata +58 -43
- data/lib/hatetepe/client/keep_alive.rb +0 -32
- data/lib/hatetepe/client/pipeline.rb +0 -19
- data/lib/hatetepe/server/app.rb +0 -85
- data/lib/hatetepe/server/proxy.rb +0 -48
- data/spec/unit/app_spec.rb +0 -125
- data/spec/unit/client/pipeline_spec.rb +0 -40
- data/spec/unit/proxy_spec.rb +0 -145
@@ -0,0 +1,93 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "hatetepe/client"
|
3
|
+
require "hatetepe/server"
|
4
|
+
|
5
|
+
describe Hatetepe::Client do
|
6
|
+
let :options do
|
7
|
+
{ host: "127.0.0.1", port: 3123 }
|
8
|
+
end
|
9
|
+
|
10
|
+
let :options2 do
|
11
|
+
{ host: "1.2.3.4", port: 3123}
|
12
|
+
end
|
13
|
+
|
14
|
+
let :client do
|
15
|
+
Hatetepe::Client.start(options)
|
16
|
+
end
|
17
|
+
|
18
|
+
before do
|
19
|
+
Hatetepe::Server.start(options.merge(timeout: 0))
|
20
|
+
end
|
21
|
+
|
22
|
+
it "times out after 5 seconds of connection inactivity" do
|
23
|
+
# only verify that 5 seconds is the default, but actually
|
24
|
+
# use a smaller timeout to keep specs fast
|
25
|
+
Hatetepe::Client::CONFIG_DEFAULTS[:timeout].should == 5
|
26
|
+
end
|
27
|
+
|
28
|
+
it "times out after 5 seconds trying to establish a connection" do
|
29
|
+
# only verify that 5 seconds is the default, but actually
|
30
|
+
# use a smaller timeout to keep specs fast
|
31
|
+
Hatetepe::Client::CONFIG_DEFAULTS[:connect_timeout].should == 5
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "with :timeout option" do
|
35
|
+
let :client do
|
36
|
+
Hatetepe::Client.start(options.merge(timeout: 0.5))
|
37
|
+
end
|
38
|
+
|
39
|
+
it "times out after n seconds of connection inactivity" do
|
40
|
+
client.should_not be_closed
|
41
|
+
EM::Synchrony.sleep(0.45)
|
42
|
+
client.should_not be_closed
|
43
|
+
|
44
|
+
EM::Synchrony.sleep(0.1)
|
45
|
+
client.should be_closed
|
46
|
+
client.should be_closed_by_timeout
|
47
|
+
client.should_not be_closed_by_connect_timeout
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "with :timeout set to 0" do
|
52
|
+
let :client do
|
53
|
+
Hatetepe::Client.start(options.merge(timeout: 0))
|
54
|
+
end
|
55
|
+
|
56
|
+
it "never times out" do
|
57
|
+
client.should_not be_closed
|
58
|
+
EM::Synchrony.sleep(0.55)
|
59
|
+
client.should_not be_closed
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "with :connect_timeout option" do
|
64
|
+
let :client do
|
65
|
+
Hatetepe::Client.start(options2.merge(connect_timeout: 0.5))
|
66
|
+
end
|
67
|
+
|
68
|
+
# this example fails if there's no network connection
|
69
|
+
it "times out after n seconds trying to establish a connection" do
|
70
|
+
client.should_not be_closed
|
71
|
+
EM::Synchrony.sleep(0.45)
|
72
|
+
client.should_not be_closed
|
73
|
+
|
74
|
+
EM::Synchrony.sleep(0.1)
|
75
|
+
client.should be_closed
|
76
|
+
client.should be_closed_by_connect_timeout
|
77
|
+
client.should_not be_closed_by_timeout
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "with :connect_timeout set to 0" do
|
82
|
+
let :client do
|
83
|
+
Hatetepe::Client.start(options2.merge(connect_timeout: 0))
|
84
|
+
end
|
85
|
+
|
86
|
+
# this example fails if there's no network connection
|
87
|
+
it "never times out trying to establish a connection" do
|
88
|
+
client.should_not be_closed
|
89
|
+
EM::Synchrony.sleep(0.55)
|
90
|
+
client.should_not be_closed
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -1,99 +1,27 @@
|
|
1
1
|
require "spec_helper"
|
2
|
-
require "hatetepe/
|
2
|
+
require "hatetepe/client"
|
3
3
|
require "hatetepe/server"
|
4
4
|
|
5
5
|
describe Hatetepe::Server, "with Keep-Alive" do
|
6
|
-
before do
|
7
|
-
$stderr = StringIO.new
|
8
|
-
|
9
|
-
FakeFS.activate!
|
10
|
-
File.open "config.ru", "w" do |f|
|
11
|
-
f.write 'run proc {|env| [200, {"Content-Type" => "text/plain"}, []] }'
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
after do
|
16
|
-
$stderr = STDERR
|
17
|
-
|
18
|
-
FakeFS.deactivate!
|
19
|
-
FakeFS::FileSystem.clear
|
20
|
-
end
|
21
|
-
|
22
|
-
let :client do
|
23
|
-
Hatetepe::Client.start :host => "127.0.0.1", :port => 30001
|
24
|
-
end
|
25
|
-
|
26
|
-
let :server do
|
27
|
-
Hatetepe::Server.any_instance
|
28
|
-
end
|
29
|
-
|
30
|
-
it "keeps the connection open for 1 seconds by default" do
|
31
|
-
command "-p 30001", 1.1 do
|
32
|
-
client
|
33
|
-
EM::Synchrony.sleep 0.95
|
34
|
-
client.should_not be_closed
|
35
|
-
EM::Synchrony.sleep 0.1
|
36
|
-
client.should be_closed
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
6
|
describe "and :timeout option" do
|
41
|
-
it "times out the connection after the specified amount of time"
|
42
|
-
command "-p 30001 -t 0.5", 0.6 do
|
43
|
-
client
|
44
|
-
EM::Synchrony.sleep 0.45
|
45
|
-
client.should_not be_closed
|
46
|
-
EM::Synchrony.sleep 0.1
|
47
|
-
client.should be_closed_by_remote
|
48
|
-
end
|
49
|
-
end
|
7
|
+
it "times out the connection after the specified amount of time"
|
50
8
|
end
|
51
9
|
|
52
10
|
describe "and :timeout option set to 0" do
|
53
|
-
it "keeps the connection open until the client closes it"
|
54
|
-
command "-p 30001 -t 0", 2 do
|
55
|
-
client
|
56
|
-
EM::Synchrony.sleep 1.95
|
57
|
-
client.should_not be_closed
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
it "closes the connection if the client sends Connection: close" do
|
63
|
-
command "-p 30001" do
|
64
|
-
client.get("/", "Connection" => "close").tap do |response|
|
65
|
-
response.headers["Connection"].should == "close"
|
66
|
-
EM::Synchrony.sync response.body
|
67
|
-
client.should be_closed_by_remote
|
68
|
-
end
|
69
|
-
end
|
11
|
+
it "keeps the connection open until the client closes it"
|
70
12
|
end
|
71
13
|
|
72
|
-
it "
|
73
|
-
|
74
|
-
|
75
|
-
response.headers["Connection"].should == "keep-alive"
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
14
|
+
it "closes the connection if the client sends Connection: close"
|
15
|
+
|
16
|
+
it "responds with Connection: keep-alive if the client also sent it"
|
79
17
|
|
80
18
|
["1.0", "0.9"].each do |version|
|
81
19
|
describe "and an HTTP #{version} client" do
|
82
|
-
after { ENV.delete "DEBUG_KEEP_ALIVE" }
|
83
|
-
|
84
20
|
it "closes the connection after one request" do
|
85
21
|
pending "http_parser.rb doesn't parse HTTP/0.9" if version == "0.9"
|
86
|
-
|
87
|
-
ENV["DEBUG_KEEP_ALIVE"] = "yes please"
|
88
|
-
|
89
|
-
command "-p 30001" do
|
90
|
-
client.get("/", {"Connection" => ""}, nil, version).tap do |response|
|
91
|
-
response.headers["Connection"].should == "close"
|
92
|
-
EM::Synchrony.sync response.body
|
93
|
-
client.should be_closed_by_remote
|
94
|
-
end
|
95
|
-
end
|
96
22
|
end
|
23
|
+
|
24
|
+
it "doesn't close the connection if the client sent Connection: Keep-Alive"
|
97
25
|
end
|
98
26
|
end
|
99
27
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "hatetepe/client"
|
3
|
+
require "hatetepe/server"
|
4
|
+
|
5
|
+
describe Hatetepe::Server do
|
6
|
+
let :options do
|
7
|
+
{ host: "127.0.0.1", port: 3123 }
|
8
|
+
end
|
9
|
+
|
10
|
+
let :client do
|
11
|
+
Hatetepe::Client.start(options.merge(timeout: 0))
|
12
|
+
end
|
13
|
+
|
14
|
+
it "times out after 5 seconds of connection inactivity" do
|
15
|
+
# only verify that 5 seconds is the default
|
16
|
+
Hatetepe::Server::CONFIG_DEFAULTS[:timeout].should == 5
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "with :timeout option" do
|
20
|
+
before do
|
21
|
+
Hatetepe::Server.start(options.merge(timeout: 0.5))
|
22
|
+
end
|
23
|
+
|
24
|
+
it "times out after the specified amount of seconds" do
|
25
|
+
client.should_not be_closed
|
26
|
+
EM::Synchrony.sleep(0.45)
|
27
|
+
client.should_not be_closed
|
28
|
+
|
29
|
+
EM::Synchrony.sleep(0.1)
|
30
|
+
client.should be_closed_by_remote
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "with :timeout set to 0" do
|
35
|
+
before do
|
36
|
+
Hatetepe::Server.start(options.merge(timeout: 0))
|
37
|
+
end
|
38
|
+
|
39
|
+
it "never times out" do
|
40
|
+
client.should_not be_closed
|
41
|
+
EM::Synchrony.sleep(0.55)
|
42
|
+
client.should_not be_closed
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,68 +1,16 @@
|
|
1
1
|
begin
|
2
2
|
require "awesome_print"
|
3
|
-
rescue LoadError
|
3
|
+
rescue LoadError
|
4
|
+
end
|
4
5
|
|
5
6
|
require "em-synchrony"
|
6
|
-
require "fakefs/safe"
|
7
7
|
|
8
|
-
RSpec.configure do |
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
config.before :all do
|
14
|
-
EM.class_eval do
|
15
|
-
class << self
|
16
|
-
attr_reader :spec_hooks
|
17
|
-
def synchrony_with_hooks(blk = nil, tail = nil, &block)
|
18
|
-
synchrony_without_hooks do
|
19
|
-
(blk || block).call
|
20
|
-
@spec_hooks.each &:call
|
21
|
-
end
|
22
|
-
end
|
23
|
-
alias_method :synchrony_without_hooks, :synchrony
|
24
|
-
alias_method :synchrony, :synchrony_with_hooks
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
config.after :all do
|
30
|
-
EM.class_eval do
|
31
|
-
class << self
|
32
|
-
remove_method :spec_hooks
|
33
|
-
alias_method :synchrony, :synchrony_without_hooks
|
34
|
-
remove_method :synchrony_with_hooks
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
config.before :each do
|
40
|
-
EM.instance_variable_set :@spec_hooks, []
|
41
|
-
end
|
42
|
-
|
43
|
-
config.after :each do
|
44
|
-
EM.instance_variable_set :@spec_hooks, nil
|
45
|
-
end
|
46
|
-
|
47
|
-
def secure_reactor(timeout = 0.05, &expectations)
|
48
|
-
finished = false
|
49
|
-
location = caller[0]
|
50
|
-
|
51
|
-
EM.spec_hooks << proc do
|
52
|
-
EM.add_timer(timeout) do
|
53
|
-
EM.stop
|
54
|
-
fail "Timeout exceeded" unless finished
|
55
|
-
end
|
56
|
-
end
|
57
|
-
EM.spec_hooks << proc do
|
58
|
-
expectations.call
|
59
|
-
finished = true
|
8
|
+
RSpec.configure do |c|
|
9
|
+
c.around do |example|
|
10
|
+
EM.synchrony do
|
11
|
+
EM.heartbeat_interval = 0.01
|
12
|
+
example.call
|
60
13
|
EM.next_tick { EM.stop }
|
61
14
|
end
|
62
15
|
end
|
63
|
-
|
64
|
-
def command(opts, timeout = 0.5, &expectations)
|
65
|
-
secure_reactor timeout, &expectations
|
66
|
-
Hatetepe::CLI.start opts.split
|
67
|
-
end
|
68
16
|
end
|