hatetepe 0.4.1 → 0.5.0.pre
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/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
|