2016-12-18 9 views
1

Я пытаюсь протестировать сетевое приложение. НО у меня мог бы быть узел в моем мозгу. Насколько я знаю, тесты в minitest проходят параллельно. Исходя из этого, я думаю, ясно, что, когда я выделить порт в настройках() он терпит неудачу, когда несколько тестов выполняются:Как написать несколько тестов для TCPSocket в Minitest

RuntimeError: Address already in use - bind(2) for nil port 2000 TCPServer new failed 

Так что это лучшая практика, чтобы сделать несколько тестов на сервере, который прослушивает порт?

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 

ответ

0

При параллельном тестировании сервера TCP каждый экземпляр сервера должен запускаться с отдельным портом. Это можно сделать, указав номер порта 0 при создании сокета. Когда номер порта 0 задан, то сокет будет привязан к случайным неиспользуемый порт:

interface = "0.0.0.0" 
port = 0 
tcp_server = TCPServer.new(interface, port) 

Вы можете узнать, какой порт сокета TCP сервер был связан с:

bound_port = @server_socket.addr[1] 

Один из способов использования эти факты, чтобы иметь сервер что-то вроде этого:

class Server 

    # Create a server instance. If the port is unspecified, 
    # or 0, then a random ephemeral port is bound to. 
    def initialize(interface: "127.0.0.1", port: 0) 
    @server_socket = TCPServer.new(interface, port) 
    ... 
    end 

    # Return the port the server socket is bound to. 
    def bound_port 
    @server_socket.addr[1] 
    end 

    ... 

end 

тест затем создает экземпляры сервера, используя порт 0:

server = Server.new(port: 0) 

При выполнении соединения с сервером, тест использует #bound_port аксессор, чтобы узнать, какой порт для подключения к:

client = TCPSocket.open("localhost", server.bound_port) 

, а затем осуществляет нормально.