I try to test a networking application. BUT I might have a knot in my brain. As far as I know the tests in minitest run parallel. On this assumption I think it is clear that when I allocate a Port in setup() it fails when several tests are run:
RuntimeError: Address already in use - bind(2) for nil port 2000 TCPServer new failed
So what is the best practise to do several tests on a server which listens on a port?
   class ServerTest < Minitest::Test
      def setup
        # -- set env variable
        ENV["conf"] = "./tc_gpio.config" 
        Thread::abort_on_exception = true
        @my_thr = Thread.start() do 
          @server = Server.new       
          @server.start
          assert @server.hi() != nil
        end
      end
      def teardown
        Thread.kill(@my_thr) # sends exit() to thr
      end
      def test_connect_and_disconnect
        sleep 1
        hostname = 'localhost'
        port = 2000
        s = TCPSocket.open(hostname, port)
        my_s = s.recvmsg()
        s.sendmsg(:set.to_s, 0) # Failes since a serialized object is expected
        my_s2 = s.recvmsg()
        assert_equal(  "READY" , my_s[0] )
        assert_equal( "eeFIN" , my_s2[0])
      end
      def test_send_command
        # fill command
        com = Command.new
        com.type = :set
        com.device_name = 'pump0'
        com.device_address = 'resource0'
        com.value = 2
        serial_com = YAML::dump(com)
        sleep 1
        hostname = 'localhost'
        port = 2000
        s = TCPSocket.open(hostname, port)
        my_s = s.recvmsg()
        s.sendmsg(serial_com, 0)
        my_s2 = s.recvmsg()
        assert_equal(  "READY" , my_s[0] )
        assert_equal( "FIN" , my_s2[0])
      end
    end
 
                        
When testing a TCP server in parallel, each instance of the server should be started with a distinct port. That can be done by specifying port number 0 when creating a socket. When port number 0 is given, the socket will be bound to a random unused port:
You can find out which port the TCP server socket was bound to:
One way to use these facts is to have a server something like this:
The test then creates server instances using port 0:
When making a connection to the server, the test uses the #bound_port accessor to find out what port to connect to:
and then carries on normally.