spec/outputs/tcp_spec.rb in logstash-output-tcp-6.1.1 vs spec/outputs/tcp_spec.rb in logstash-output-tcp-6.1.2

- old
+ new

@@ -106,10 +106,37 @@ subject.send :setup_ssl end end + context "client mode" do + before { subject.register } + + let(:config) { super().merge 'mode' => 'client' } + + it 'writes payload data' do + Thread.start { sleep 0.25; subject.receive event } + + socket = server.accept + read = socket.sysread(100) + + expect( read.size ).to be > 0 + expect( read ).to eq(JSON.generate(event)) + end + + it 'writes payload data in multiple operations' do + full_payload = JSON.generate(event) + Thread.start { sleep 0.25; subject.receive event } + + socket = server.accept + first_read = socket.sysread((full_payload.length / 2)) + second_read = socket.sysread(((full_payload.length / 2) + 1)) + + expect( "#{first_read}#{second_read}" ).to eq(full_payload) + end + end + context "when enabling SSL" do let(:config) { super().merge("ssl_enable" => true, 'codec' => 'plain') } context "and not providing a certificate/key pair" do it "registers without error" do expect { subject.register }.to_not raise_error @@ -223,9 +250,62 @@ it "registers without error" do expect { subject.register }.to_not raise_error end + end + end + + context "and protocol is TLSv1.3" do + let(:key_file) { File.join(FIXTURES_PATH, 'plaintext/instance.key') } + let(:crt_file) { File.join(FIXTURES_PATH, 'plaintext/instance.crt') } + let(:config) { super().merge("ssl_cert" => crt_file, "ssl_key" => key_file) } + + let(:secure_server) do + ssl_context = OpenSSL::SSL::SSLContext.new + ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE + ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(crt_file)) + ssl_context.key = OpenSSL::PKey::RSA.new(File.read(key_file), nil) + ssl_context.min_version = OpenSSL::SSL::TLS1_3_VERSION + OpenSSL::SSL::SSLServer.new(server, ssl_context) + end + + before(:each) do + subject.register + end + + after(:each) do + secure_server.close rescue nil + end + + let(:message) { "a" } + let(:buffer) { "" } + + # This test confirms that this plugin is able to write to a TLS socket + # multiple times. + # Previous implementation performed an IO.select first and called sysread + # if select signaled the socket was ready to read. + # For TLS1_3, due to control messages it may happen that the underlying + # socket is marked as readable but there is no new data available, + # causing a read to block forever. + # This test will raise a Timeout exception with the old implementation. + it 'successfully writes two messages' do + thread = Thread.start do + expect { + client = secure_server.accept + Timeout::timeout(5) do + buffer << client.sysread(1) # read first message + subject.receive(message) + buffer << client.sysread(1) # read second message + client.close + end + }.to_not raise_error + end + sleep 0.1 until thread.status == "sleep" # wait for TCP port to open + subject.receive(message) # send first message to unblock call to `accept` + thread.join(2) + + expect(buffer).to eq(message * 2) end end end end