spec/stream_spec.rb in http-2-0.6.3 vs spec/stream_spec.rb in http-2-0.7.0
- old
+ new
@@ -10,12 +10,12 @@
it "should initiliaze all streams to IDLE" do
@stream.state.should eq :idle
end
it "should set custom stream priority" do
- stream = @client.new_stream(priority: 3)
- stream.priority.should eq 3
+ stream = @client.new_stream(weight: 3, dependency: 2, exclusive: true)
+ stream.weight.should eq 3
end
context "reserved (local)" do
before(:each) { @stream.send PUSH_PROMISE }
@@ -53,12 +53,12 @@
@stream.receive RST_STREAM
@stream.state.should eq :closed
end
it "should reprioritize stream on PRIORITY" do
- @stream.receive PRIORITY.merge({priority: 30})
- @stream.priority.should eq 30
+ expect { @stream.receive PRIORITY }.to_not raise_error
+ @stream.weight.should eq 20
end
end
context "reserved (remote)" do
before(:each) { @stream.receive PUSH_PROMISE }
@@ -93,12 +93,12 @@
@stream.receive RST_STREAM
@stream.state.should eq :closed
end
it "should reprioritize stream on PRIORITY" do
- @stream.send PRIORITY
- @stream.priority.should eq 15
+ expect { @stream.send PRIORITY }.to_not raise_error
+ @stream.weight.should eq 20
end
end
context "open" do
before(:each) { @stream.receive HEADERS }
@@ -114,21 +114,21 @@
expect { @stream.dup.receive type }.to_not raise_error
end
end
it "should transition to half closed (local) if sending END_STREAM" do
- [DATA, HEADERS, CONTINUATION].each do |frame|
+ [DATA, HEADERS].each do |frame|
s, f = @stream.dup, frame.dup
f[:flags] = [:end_stream]
s.send f
s.state.should eq :half_closed_local
end
end
it "should transition to half closed (remote) if receiving END_STREAM" do
- [DATA, HEADERS, CONTINUATION].each do |frame|
+ [DATA, HEADERS].each do |frame|
s, f = @stream.dup, frame.dup
f[:flags] = [:end_stream]
s.receive f
s.state.should eq :half_closed_remote
@@ -171,12 +171,12 @@
sr.on(:active) { openr = true }
sp.receive HEADERS
sr.send HEADERS
- openp.should be_true
- openr.should be_true
+ openp.should be_truthy
+ openr.should be_truthy
end
it "should not emit :active on transition from open" do
order, stream = [], @client.new_stream
@@ -200,12 +200,12 @@
sr.on(:close) { closer = true }
sp.receive RST_STREAM
sr.close
- closep.should be_true
- closer.should be_true
+ closep.should be_truthy
+ closer.should be_truthy
end
it "should emit :close after frame is processed" do
order, stream = [], @client.new_stream
@@ -234,11 +234,11 @@
context "half closed (local)" do
before(:each) { @stream.send HEADERS_END_STREAM }
it "should raise error on attempt to send frames" do
- (FRAME_TYPES - [RST_STREAM]).each do |frame|
+ (FRAME_TYPES - [PRIORITY, RST_STREAM]).each do |frame|
expect { @stream.dup.send frame }.to raise_error StreamError
end
end
it "should transition to closed on receipt of END_STREAM flag" do
@@ -265,10 +265,15 @@
expect { @stream.receive WINDOW_UPDATE }.to_not raise_error
expect { @stream.receive PRIORITY }.to_not raise_error
@stream.state.should eq :half_closed_local
end
+ it "should reprioritize stream on PRIORITY" do
+ expect { @stream.send PRIORITY }.to_not raise_error
+ @stream.weight.should eq 20
+ end
+
it "should emit :half_close event on transition" do
order = []
stream = @client.new_stream
stream.on(:active) { order << :active }
stream.on(:half_close) { order << :half_close }
@@ -284,27 +289,27 @@
closed = false
@stream.on(:close) { closed = true }
@stream.receive RST_STREAM
@stream.state.should eq :closed
- closed.should be_true
+ closed.should be_truthy
end
end
context "half closed (remote)" do
before(:each) { @stream.receive HEADERS_END_STREAM }
it "should raise STREAM_CLOSED error on reciept of frames" do
- (FRAME_TYPES - [RST_STREAM, WINDOW_UPDATE]).each do |frame|
+ (FRAME_TYPES - [PRIORITY, RST_STREAM, WINDOW_UPDATE]).each do |frame|
expect {
@stream.dup.receive frame
}.to raise_error(StreamClosed)
end
end
it "should transition to closed if END_STREAM flag is sent" do
- [DATA, HEADERS, CONTINUATION].each do |frame|
+ [DATA, HEADERS].each do |frame|
s, f = @stream.dup, frame.dup
f[:flags] = [:end_stream]
s.on(:close) { s.state.should eq :closed }
s.send f
@@ -325,10 +330,15 @@
it "should ignore received WINDOW_UPDATE frames" do
expect { @stream.receive WINDOW_UPDATE }.to_not raise_error
@stream.state.should eq :half_closed_remote
end
+ it "should reprioritize stream on PRIORITY" do
+ expect { @stream.receive PRIORITY }.to_not raise_error
+ @stream.weight.should eq 20
+ end
+
it "should emit :half_close event on transition" do
order = []
stream = @client.new_stream
stream.on(:active) { order << :active }
stream.on(:half_close) { order << :half_close }
@@ -344,11 +354,11 @@
closed = false
@stream.on(:close) { closed = true }
@stream.close
@stream.state.should eq :closed
- closed.should be_true
+ closed.should be_truthy
end
end
context "closed" do
context "remote closed stream" do
@@ -356,32 +366,40 @@
@stream.send HEADERS_END_STREAM # half closed local
@stream.receive HEADERS_END_STREAM # closed by remote
end
it "should raise STREAM_CLOSED on attempt to send frames" do
- (FRAME_TYPES - [RST_STREAM]).each do |frame|
+ (FRAME_TYPES - [PRIORITY, RST_STREAM]).each do |frame|
expect {
@stream.dup.send frame
}.to raise_error(StreamClosed)
end
end
it "should raise STREAM_CLOSED on receipt of frame" do
- (FRAME_TYPES - [RST_STREAM]).each do |frame|
+ (FRAME_TYPES - [PRIORITY, RST_STREAM, WINDOW_UPDATE]).each do |frame|
expect {
@stream.dup.receive frame
}.to raise_error(StreamClosed)
end
end
- it "should allow RST_STREAM to be sent" do
+ it "should allow PRIORITY, RST_STREAM to be sent" do
+ expect { @stream.send PRIORITY }.to_not raise_error
expect { @stream.send RST_STREAM }.to_not raise_error
end
- it "should not send RST_STREAM on receipt of RST_STREAM" do
+ it "should allow PRIORITY, RST_STREAM to be received" do
+ expect { @stream.receive PRIORITY }.to_not raise_error
expect { @stream.receive RST_STREAM }.to_not raise_error
end
+
+ it "should reprioritize stream on PRIORITY" do
+ expect { @stream.receive PRIORITY }.to_not raise_error
+ @stream.weight.should eq 20
+ end
+
end
context "local closed via RST_STREAM frame" do
before(:each) do
@stream.send HEADERS # open
@@ -405,96 +423,101 @@
# RST_STREAM. PUSH_PROMISE causes a stream to become "reserved".
# ...
# We're auto RST'ing PUSH streams in connection class, hence
# skipping this transition for now.
#end
+
end
- context "local closed via END_STREAM flag" do
- before(:each) do
- @stream.send HEADERS # open
- @stream.send DATA # contains end_stream flag
- end
+ # FIXME: Isn't this test same as "half closed (local)"?
+ # context "local closed via END_STREAM flag" do
+ # before(:each) do
+ # @stream.send HEADERS # open
+ # @stream.send DATA # contains end_stream flag
+ # end
- it "should ignore received frames" do
- FRAME_TYPES.each do |frame|
- expect { @stream.dup.receive frame }.to_not raise_error
- end
- end
- end
+ # it "should ignore received frames" do
+ # FRAME_TYPES.each do |frame|
+ # expect { @stream.dup.receive frame }.to_not raise_error
+ # end
+ # end
+ # end
+
end
end # end stream states
+ # TODO: add test cases to ensure on(:priority) emitted after close
+
context "flow control" do
it "should initialize to default flow control window" do
- @stream.window.should eq DEFAULT_FLOW_WINDOW
+ @stream.remote_window.should eq DEFAULT_FLOW_WINDOW
end
it "should update window size on DATA frames only" do
@stream.send HEADERS # go to open
- @stream.window.should eq DEFAULT_FLOW_WINDOW
+ @stream.remote_window.should eq DEFAULT_FLOW_WINDOW
(FRAME_TYPES - [DATA,PING,GOAWAY,SETTINGS]).each do |frame|
s = @stream.dup
s.send frame
- s.window.should eq DEFAULT_FLOW_WINDOW
+ s.remote_window.should eq DEFAULT_FLOW_WINDOW
end
@stream.send DATA
- @stream.window.should eq DEFAULT_FLOW_WINDOW - DATA[:payload].bytesize
+ @stream.remote_window.should eq DEFAULT_FLOW_WINDOW - DATA[:payload].bytesize
end
it "should update window size on receipt of WINDOW_UPDATE" do
@stream.send HEADERS
@stream.send DATA
@stream.receive WINDOW_UPDATE
- @stream.window.should eq (
+ @stream.remote_window.should eq (
DEFAULT_FLOW_WINDOW - DATA[:payload].bytesize + WINDOW_UPDATE[:increment]
)
end
it "should observe session flow control" do
settings, data = SETTINGS.dup, DATA.dup
- settings[:payload] = { settings_initial_window_size: 1000 }
+ settings[:payload] = [[:settings_initial_window_size, 1000]]
settings[:stream] = 0
framer = Framer.new
@client << framer.generate(settings)
s1 = @client.new_stream
s1.send HEADERS
s1.send data.merge({payload: "x" * 900, flags: []})
- s1.window.should eq 100
+ s1.remote_window.should eq 100
s1.send data.merge({payload: "x" * 200})
- s1.window.should eq 0
+ s1.remote_window.should eq 0
s1.buffered_amount.should eq 100
@client << framer.generate(WINDOW_UPDATE.merge({
stream: s1.id, increment: 1000
}))
s1.buffered_amount.should eq 0
- s1.window.should eq 900
+ s1.remote_window.should eq 900
end
end
context "client API" do
it ".reprioritize should emit PRIORITY frame" do
@stream.should_receive(:send) do |frame|
frame[:type].should eq :priority
- frame[:priority].should eq 30
+ frame[:weight].should eq 30
end
- @stream.reprioritize 30
+ @stream.reprioritize weight: 30
end
it ".reprioritize should raise error if invoked by server" do
srv = Server.new
stream = srv.new_stream
- expect { stream.reprioritize(10) }.to raise_error(StreamError)
+ expect { stream.reprioritize(weight: 10) }.to raise_error(StreamError)
end
it ".headers should emit HEADERS frames" do
payload = {
':method' => 'GET',
@@ -526,11 +549,11 @@
end
@stream.data("text")
end
it ".data should split large DATA frames" do
- data = "x" * HTTP2::MAX_FRAME_SIZE * 2
+ data = "x" * 16384 * 2
@stream.stub(:send)
@stream.should_receive(:send).exactly(3).times
@stream.data(data + "x")
end
@@ -562,11 +585,11 @@
@client.on(:frame) {|bytes| @srv << bytes }
@client_stream = @client.new_stream
end
it "should emit received headers via on(:headers)" do
- headers, recv = {"header" => "value"}, nil
+ headers, recv = [["header", "value"]], nil
@srv.on(:stream) do |stream|
stream.on(:headers) {|h| recv = h}
end
@client_stream.headers(headers)
@@ -583,30 +606,34 @@
@client_stream.headers({"key" => "value"})
@client_stream.data(payload)
end
- it "should emit received priority via on(:priority)" do
- new_priority, recv = 15, 0
+ it "should emit received priority parameters via on(:priority)" do
+ new_weight, new_dependency = 15, @client_stream.id + 2
+ callback_called = false
@srv.on(:stream) do |stream|
stream.on(:priority) do |pri|
- pri.should eq new_priority
+ callback_called = true
+ pri.is_a?(Hash).should be
+ pri[:weight].should eq new_weight
+ pri[:dependency].should eq new_dependency
end
end
@client_stream.headers({"key" => "value"})
- @client_stream.reprioritize(new_priority)
+ @client_stream.reprioritize(weight: new_weight, dependency: new_dependency)
+ callback_called.should be
end
context "push" do
before(:each) do
@srv.on(:frame) {|bytes| @client << bytes }
@srv.on(:stream) do |stream|
@server_stream = stream
end
- # @srv << @frm.generate(SETTINGS)
@client_stream.headers({"key" => "value"})
end
it ".promise should emit server initiated stream" do
push = nil
@@ -641,32 +668,32 @@
order.should eq [:reserved, :active, :half_close, :close]
end
it "client: headers > active > headers > .. > data > close" do
- order, headers = [], {}
+ order, headers = [], []
@client.on(:promise) do |push|
order << :reserved
push.on(:active) { order << :active }
push.on(:data) { order << :data }
push.on(:half_close){ order << :half_close }
push.on(:close) { order << :close }
push.on(:headers) do |h|
order << :headers
- headers.merge!(h)
+ headers += h
end
push.id.should be_even
end
@server_stream.promise({"key" => "val"}) do |push|
push.headers("key2" => "val2")
push.data("somedata")
end
- headers.should eq({"key" => "val", "key2" => "val2"})
+ headers.should eq([["key", "val"], ["key2", "val2"]])
order.should eq [:reserved, :headers, :active, :headers,
:half_close, :data, :close]
end
end