2014-02-21 2 views
1

Ситуация:Проверка, имеется ли разъем порта

У меня есть приложение, которое имеет сервер TCP в качестве его части (на основе socketserver), и я хочу проверить его функционально.

Я создал себе тестирования подмешать, который я использую в каждом тесте:

class AppProcessManagingMixin: 
    _used_tcp_ports = set() 

    def start_my_app(self): 
     port = self._take_tcp_port() 
     prepare_config_with_given_tcp_port(port) 
     # use prepared config by subprocess below 
     Popen([python_executable_path, my_app_name, ...).start() 

    def _take_tcp_port(self): 
     available_found = False 
     while not available_found: 
      port = random.randint(9000, 9999) # these ints are arbitrary here 
      available_found = port not in self._used_tcp_ports 
     self._used_tcp_ports.add(port) 
     return port 

    def stop_my_app(self): 
     so_something_that_Im_sure_will_stop_my_app_after_a_few_seconds() 

Каждый тестовый случай setUp() называет self.start_my_app(), и каждый tearDown() - self.stop_my_app(), и я могу рассчитывать на прекращение моего приложения. Мне нужно много экземпляров моего приложения (и не может запускать/останавливать приложение в настройке/разборке в классе), потому что некоторые из моих тестов проверяют, хорошо ли работает приложение в сценариях, начиная с пустой рабочей директории (мне просто нужен «пустой» экземпляр приложения для этих тестов).

У меня проблема со вторым методом, _take_tcp_port. Прежде чем я это представил, у меня часто возникали проблемы с уже принятым адресом (потому что все тесты пытались запустить TCP-сервер на том же порту). Теперь это происходит не так часто, но все же - бывает.

Я знаю, что он зависит от системы, и через несколько секунд порт будет доступен снова, но он сделает автоматическое тестирование сложнее.

Вопрос:

Как проверить, доступен ли для TCP сервера некоторые адрес (хост и порт)? Я хочу проверить его в _take_tcp_port, чтобы убедиться, что тест не будет терпеть неудачу, потому что экземпляр приложения имеет проблемы с принятым портом.

исследований я сделал:

Я просмотрел 1-й страницы следующих запросов Google:

  • проверки, если порт открыт питон
  • проверить, если порт доступен питон
  • открыть доступный порт

и все Подходы, которые я нашел, основываются на попытке получить сокет. Дело в том, что если я успешно получаю сокет, я могу быть уверен, что этот порт открыт, но поскольку я это сделал, я не могу быть уверен, что мое приложение сможет его получить. Мне нужно что-то без побочных эффектов.

Платформа

Это должно быть мультиплатформенной (по крайней мере, Windows, Linux, MacOS). Он должен работать как минимум в p3.3 +. Если «есть lib для этого», которого будет достаточно;)

ответ

1

Вам не нужно вручную сканировать доступный порт - ОС сделает это за вас. Просто укажите порт 0 при вызове bind(), и ОС выберет один. Это часто полезно для тестирования - вы можете запустить одну конечную точку с портом 0, спросить систему, какой порт он действительно получил (getsockaddr), а затем запустить вторую конечную точку с этим номером порта.

+0

Это полезно, но как я могу получить этот порт вне процесса Popened?Некоторым тестам нужно будет подключиться к этому TCP-серверу и быть как можно ближе к симуляции реальных сценариев, я хочу запустить это с помощью Popen, возможно, с оболочкой = True, чтобы изолировать процессы тестирования и процессы приложений (вместо того, чтобы называть его основной() в процессе тестирования в дополнительном потоке или многопроцессорном процессе. Процесс. –

+0

Один из вариантов - передать аргумент командной строки программе через Popen, который указывает имя файла, в который программа будет записывать номер порта, как только он узнает. Или даже ваша пусковая установка прослушивает любой порт и передаёт этот номер порта ребенку, и ребенок будет использовать это для отправки номера порта обратно. Немного путаный, тот, но он будет работать, если вы не захотите использовать файловую систему для этого IPC. –

+0

Это означало бы, что мне нужно реализовать что-то в приложении, которое не имеет реального использования, но создается только для тестов. Это я считаю плохой практикой - я начинаю связывать логику приложений и логику тестирования, и это плохо. Тем не менее, вероятно, мы собираемся добавить что-то, что использует конфигурацию (копирует ее) в рабочее пространство, чтобы можно было проверить состояние приложений - тогда мы будем использовать этот подход. Благодаря! –

Смежные вопросы