How to close a TCP server during Rspec testing?

Viewed 67

I'm trying to test a TCP Server in Rspec. Ideally I wan't to use a fresh server in each example. So I planned to use before and after hooks to create and close a new server for each example.

Problem is that even after closing all sockets (from both clients and server) the port isn't freed. So I get an "Adress already in use" error after the first example. Is there any recommended way to close a TCP server to avoid this?

I recreated this problem with a simplified version of all three elements. Even with this I can't get the server to release the port.

Thanks in advance.

Server

require 'socket'

class TestServer
  def initialize(socket_address, socket_port)
    @socket_address = socket_address
    @socket_port = socket_port
  end

  def run
    server = TCPServer.new(@socket_address, @socket_port)

    connection = server.accept
    connection.puts 'close client'
    puts "closing connection"
    connection.close
    @condition = true
    puts "Ok, the port is free"
  end
end

Client:

require 'socket'

class TestClient
  def initialize(socket_address, socket_port)
    @socket_address = socket_address
    @socket_port = socket_port
  end

  def run 
    @socket = TCPSocket.open(@socket_address, @socket_port)

    puts "connected"
  end

  def read 
    if (message = @socket.gets) == "close client" 
      puts "closing"
    @socket.close
    end
  end

  def write(message)
    @socket.puts message
  end
end

Rspec test:

require_relative "../lib/TestServer"
require_relative "../lib/TestClient"

require 'rspec/expectations'


RSpec.describe "Testing" do
  before(:each) do
    test_server = TestServer.new('localhost', 8080)
    Thread.new{test_server.run}
    client = TestClient.new('localhost', 8080)
    client.run
    client.read
  end


  it "A" do
  end
  it "B" do
  end
  it "C" do
  end  
end
0 Answers
Related