summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/thrift/lib/rb/spec/base_transport_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'src/jaegertracing/thrift/lib/rb/spec/base_transport_spec.rb')
-rw-r--r--src/jaegertracing/thrift/lib/rb/spec/base_transport_spec.rb388
1 files changed, 388 insertions, 0 deletions
diff --git a/src/jaegertracing/thrift/lib/rb/spec/base_transport_spec.rb b/src/jaegertracing/thrift/lib/rb/spec/base_transport_spec.rb
new file mode 100644
index 000000000..d2f60aaea
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/rb/spec/base_transport_spec.rb
@@ -0,0 +1,388 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+require 'spec_helper'
+
+describe 'BaseTransport' do
+
+ describe Thrift::TransportException do
+ it "should make type accessible" do
+ exc = Thrift::TransportException.new(Thrift::TransportException::ALREADY_OPEN, "msg")
+ expect(exc.type).to eq(Thrift::TransportException::ALREADY_OPEN)
+ expect(exc.message).to eq("msg")
+ end
+ end
+
+ describe Thrift::BaseTransport do
+ it "should read the specified size" do
+ transport = Thrift::BaseTransport.new
+ expect(transport).to receive(:read).with(40).ordered.and_return("10 letters")
+ expect(transport).to receive(:read).with(30).ordered.and_return("fifteen letters")
+ expect(transport).to receive(:read).with(15).ordered.and_return("more characters")
+ expect(transport.read_all(40)).to eq("10 lettersfifteen lettersmore characters")
+ end
+
+ it "should stub out the rest of the methods" do
+ # can't test for stubbiness, so just make sure they're defined
+ [:open?, :open, :close, :read, :write, :flush].each do |sym|
+ expect(Thrift::BaseTransport.method_defined?(sym)).to be_truthy
+ end
+ end
+
+ it "should alias << to write" do
+ expect(Thrift::BaseTransport.instance_method(:<<)).to eq(Thrift::BaseTransport.instance_method(:write))
+ end
+
+ it "should provide a reasonable to_s" do
+ expect(Thrift::BaseTransport.new.to_s).to eq("base")
+ end
+ end
+
+ describe Thrift::BaseServerTransport do
+ it "should stub out its methods" do
+ [:listen, :accept, :close].each do |sym|
+ expect(Thrift::BaseServerTransport.method_defined?(sym)).to be_truthy
+ end
+ end
+ end
+
+ describe Thrift::BaseTransportFactory do
+ it "should return the transport it's given" do
+ transport = double("Transport")
+ expect(Thrift::BaseTransportFactory.new.get_transport(transport)).to eql(transport)
+ end
+
+ it "should provide a reasonable to_s" do
+ expect(Thrift::BaseTransportFactory.new.to_s).to eq("base")
+ end
+ end
+
+ describe Thrift::BufferedTransport do
+ it "should provide a to_s that describes the encapsulation" do
+ trans = double("Transport")
+ expect(trans).to receive(:to_s).and_return("mock")
+ expect(Thrift::BufferedTransport.new(trans).to_s).to eq("buffered(mock)")
+ end
+
+ it "should pass through everything but write/flush/read" do
+ trans = double("Transport")
+ expect(trans).to receive(:open?).ordered.and_return("+ open?")
+ expect(trans).to receive(:open).ordered.and_return("+ open")
+ expect(trans).to receive(:flush).ordered # from the close
+ expect(trans).to receive(:close).ordered.and_return("+ close")
+ btrans = Thrift::BufferedTransport.new(trans)
+ expect(btrans.open?).to eq("+ open?")
+ expect(btrans.open).to eq("+ open")
+ expect(btrans.close).to eq("+ close")
+ end
+
+ it "should buffer reads in chunks of #{Thrift::BufferedTransport::DEFAULT_BUFFER}" do
+ trans = double("Transport")
+ expect(trans).to receive(:read).with(Thrift::BufferedTransport::DEFAULT_BUFFER).and_return("lorum ipsum dolor emet")
+ btrans = Thrift::BufferedTransport.new(trans)
+ expect(btrans.read(6)).to eq("lorum ")
+ expect(btrans.read(6)).to eq("ipsum ")
+ expect(btrans.read(6)).to eq("dolor ")
+ expect(btrans.read(6)).to eq("emet")
+ end
+
+ it "should buffer writes and send them on flush" do
+ trans = double("Transport")
+ btrans = Thrift::BufferedTransport.new(trans)
+ btrans.write("one/")
+ btrans.write("two/")
+ btrans.write("three/")
+ expect(trans).to receive(:write).with("one/two/three/").ordered
+ expect(trans).to receive(:flush).ordered
+ btrans.flush
+ end
+
+ it "should only send buffered data once" do
+ trans = double("Transport")
+ btrans = Thrift::BufferedTransport.new(trans)
+ btrans.write("one/")
+ btrans.write("two/")
+ btrans.write("three/")
+ expect(trans).to receive(:write).with("one/two/three/")
+ allow(trans).to receive(:flush)
+ btrans.flush
+ # Nothing to flush with no data
+ btrans.flush
+ end
+
+ it "should flush on close" do
+ trans = double("Transport")
+ expect(trans).to receive(:close)
+ btrans = Thrift::BufferedTransport.new(trans)
+ expect(btrans).to receive(:flush)
+ btrans.close
+ end
+
+ it "should not write to socket if there's no data" do
+ trans = double("Transport")
+ expect(trans).to receive(:flush)
+ btrans = Thrift::BufferedTransport.new(trans)
+ btrans.flush
+ end
+ end
+
+ describe Thrift::BufferedTransportFactory do
+ it "should wrap the given transport in a BufferedTransport" do
+ trans = double("Transport")
+ btrans = double("BufferedTransport")
+ expect(Thrift::BufferedTransport).to receive(:new).with(trans).and_return(btrans)
+ expect(Thrift::BufferedTransportFactory.new.get_transport(trans)).to eq(btrans)
+ end
+
+ it "should provide a reasonable to_s" do
+ expect(Thrift::BufferedTransportFactory.new.to_s).to eq("buffered")
+ end
+ end
+
+ describe Thrift::FramedTransport do
+ before(:each) do
+ @trans = double("Transport")
+ end
+
+ it "should provide a to_s that describes the encapsulation" do
+ trans = double("Transport")
+ expect(trans).to receive(:to_s).and_return("mock")
+ expect(Thrift::FramedTransport.new(trans).to_s).to eq("framed(mock)")
+ end
+
+ it "should pass through open?/open/close" do
+ ftrans = Thrift::FramedTransport.new(@trans)
+ expect(@trans).to receive(:open?).ordered.and_return("+ open?")
+ expect(@trans).to receive(:open).ordered.and_return("+ open")
+ expect(@trans).to receive(:close).ordered.and_return("+ close")
+ expect(ftrans.open?).to eq("+ open?")
+ expect(ftrans.open).to eq("+ open")
+ expect(ftrans.close).to eq("+ close")
+ end
+
+ it "should pass through read when read is turned off" do
+ ftrans = Thrift::FramedTransport.new(@trans, false, true)
+ expect(@trans).to receive(:read).with(17).ordered.and_return("+ read")
+ expect(ftrans.read(17)).to eq("+ read")
+ end
+
+ it "should pass through write/flush when write is turned off" do
+ ftrans = Thrift::FramedTransport.new(@trans, true, false)
+ expect(@trans).to receive(:write).with("foo").ordered.and_return("+ write")
+ expect(@trans).to receive(:flush).ordered.and_return("+ flush")
+ expect(ftrans.write("foo")).to eq("+ write")
+ expect(ftrans.flush).to eq("+ flush")
+ end
+
+ it "should return a full frame if asked for >= the frame's length" do
+ frame = "this is a frame"
+ expect(@trans).to receive(:read_all).with(4).and_return("\000\000\000\017")
+ expect(@trans).to receive(:read_all).with(frame.length).and_return(frame)
+ expect(Thrift::FramedTransport.new(@trans).read(frame.length + 10)).to eq(frame)
+ end
+
+ it "should return slices of the frame when asked for < the frame's length" do
+ frame = "this is a frame"
+ expect(@trans).to receive(:read_all).with(4).and_return("\000\000\000\017")
+ expect(@trans).to receive(:read_all).with(frame.length).and_return(frame)
+ ftrans = Thrift::FramedTransport.new(@trans)
+ expect(ftrans.read(4)).to eq("this")
+ expect(ftrans.read(4)).to eq(" is ")
+ expect(ftrans.read(16)).to eq("a frame")
+ end
+
+ it "should return nothing if asked for <= 0" do
+ expect(Thrift::FramedTransport.new(@trans).read(-2)).to eq("")
+ end
+
+ it "should pull a new frame when the first is exhausted" do
+ frame = "this is a frame"
+ frame2 = "yet another frame"
+ expect(@trans).to receive(:read_all).with(4).and_return("\000\000\000\017", "\000\000\000\021")
+ expect(@trans).to receive(:read_all).with(frame.length).and_return(frame)
+ expect(@trans).to receive(:read_all).with(frame2.length).and_return(frame2)
+ ftrans = Thrift::FramedTransport.new(@trans)
+ expect(ftrans.read(4)).to eq("this")
+ expect(ftrans.read(8)).to eq(" is a fr")
+ expect(ftrans.read(6)).to eq("ame")
+ expect(ftrans.read(4)).to eq("yet ")
+ expect(ftrans.read(16)).to eq("another frame")
+ end
+
+ it "should buffer writes" do
+ ftrans = Thrift::FramedTransport.new(@trans)
+ expect(@trans).not_to receive(:write)
+ ftrans.write("foo")
+ ftrans.write("bar")
+ ftrans.write("this is a frame")
+ end
+
+ it "should write slices of the buffer" do
+ ftrans = Thrift::FramedTransport.new(@trans)
+ ftrans.write("foobar", 3)
+ ftrans.write("barfoo", 1)
+ allow(@trans).to receive(:flush)
+ expect(@trans).to receive(:write).with("\000\000\000\004foob")
+ ftrans.flush
+ end
+
+ it "should flush frames with a 4-byte header" do
+ ftrans = Thrift::FramedTransport.new(@trans)
+ expect(@trans).to receive(:write).with("\000\000\000\035one/two/three/this is a frame").ordered
+ expect(@trans).to receive(:flush).ordered
+ ftrans.write("one/")
+ ftrans.write("two/")
+ ftrans.write("three/")
+ ftrans.write("this is a frame")
+ ftrans.flush
+ end
+
+ it "should not flush the same buffered data twice" do
+ ftrans = Thrift::FramedTransport.new(@trans)
+ expect(@trans).to receive(:write).with("\000\000\000\007foo/bar")
+ allow(@trans).to receive(:flush)
+ ftrans.write("foo")
+ ftrans.write("/bar")
+ ftrans.flush
+ expect(@trans).to receive(:write).with("\000\000\000\000")
+ ftrans.flush
+ end
+ end
+
+ describe Thrift::FramedTransportFactory do
+ it "should wrap the given transport in a FramedTransport" do
+ trans = double("Transport")
+ expect(Thrift::FramedTransport).to receive(:new).with(trans)
+ Thrift::FramedTransportFactory.new.get_transport(trans)
+ end
+
+ it "should provide a reasonable to_s" do
+ expect(Thrift::FramedTransportFactory.new.to_s).to eq("framed")
+ end
+ end
+
+ describe Thrift::MemoryBufferTransport do
+ before(:each) do
+ @buffer = Thrift::MemoryBufferTransport.new
+ end
+
+ it "should provide a reasonable to_s" do
+ expect(@buffer.to_s).to eq("memory")
+ end
+
+ it "should accept a buffer on input and use it directly" do
+ s = "this is a test"
+ @buffer = Thrift::MemoryBufferTransport.new(s)
+ expect(@buffer.read(4)).to eq("this")
+ s.slice!(-4..-1)
+ expect(@buffer.read(@buffer.available)).to eq(" is a ")
+ end
+
+ it "should always remain open" do
+ expect(@buffer).to be_open
+ @buffer.close
+ expect(@buffer).to be_open
+ end
+
+ it "should respond to peek and available" do
+ @buffer.write "some data"
+ expect(@buffer.peek).to be_truthy
+ expect(@buffer.available).to eq(9)
+ @buffer.read(4)
+ expect(@buffer.peek).to be_truthy
+ expect(@buffer.available).to eq(5)
+ @buffer.read(5)
+ expect(@buffer.peek).to be_falsey
+ expect(@buffer.available).to eq(0)
+ end
+
+ it "should be able to reset the buffer" do
+ @buffer.write "test data"
+ @buffer.reset_buffer("foobar")
+ expect(@buffer.available).to eq(6)
+ expect(@buffer.read(@buffer.available)).to eq("foobar")
+ @buffer.reset_buffer
+ expect(@buffer.available).to eq(0)
+ end
+
+ it "should copy the given string when resetting the buffer" do
+ s = "this is a test"
+ @buffer.reset_buffer(s)
+ expect(@buffer.available).to eq(14)
+ @buffer.read(10)
+ expect(@buffer.available).to eq(4)
+ expect(s).to eq("this is a test")
+ end
+
+ it "should return from read what was given in write" do
+ @buffer.write "test data"
+ expect(@buffer.read(4)).to eq("test")
+ expect(@buffer.read(@buffer.available)).to eq(" data")
+ @buffer.write "foo"
+ @buffer.write " bar"
+ expect(@buffer.read(@buffer.available)).to eq("foo bar")
+ end
+
+ it "should throw an EOFError when there isn't enough data in the buffer" do
+ @buffer.reset_buffer("")
+ expect{@buffer.read(1)}.to raise_error(EOFError)
+
+ @buffer.reset_buffer("1234")
+ expect{@buffer.read(5)}.to raise_error(EOFError)
+ end
+ end
+
+ describe Thrift::IOStreamTransport do
+ before(:each) do
+ @input = double("Input", :closed? => false)
+ @output = double("Output", :closed? => false)
+ @trans = Thrift::IOStreamTransport.new(@input, @output)
+ end
+
+ it "should provide a reasonable to_s" do
+ expect(@input).to receive(:to_s).and_return("mock_input")
+ expect(@output).to receive(:to_s).and_return("mock_output")
+ expect(@trans.to_s).to eq("iostream(input=mock_input,output=mock_output)")
+ end
+
+ it "should be open as long as both input or output are open" do
+ expect(@trans).to be_open
+ allow(@input).to receive(:closed?).and_return(true)
+ expect(@trans).to be_open
+ allow(@input).to receive(:closed?).and_return(false)
+ allow(@output).to receive(:closed?).and_return(true)
+ expect(@trans).to be_open
+ allow(@input).to receive(:closed?).and_return(true)
+ expect(@trans).not_to be_open
+ end
+
+ it "should pass through read/write to input/output" do
+ expect(@input).to receive(:read).with(17).and_return("+ read")
+ expect(@output).to receive(:write).with("foobar").and_return("+ write")
+ expect(@trans.read(17)).to eq("+ read")
+ expect(@trans.write("foobar")).to eq("+ write")
+ end
+
+ it "should close both input and output when closed" do
+ expect(@input).to receive(:close)
+ expect(@output).to receive(:close)
+ @trans.close
+ end
+ end
+end