Искусственное создание ошибки тайм-аута соединения
У меня была ошибка в нашем программном обеспечении, возникающая при получении тайм-аута соединения. Эти ошибки очень редки (обычно, когда моя связь прерывается нашей внутренней сетью). Как я могу создать такой эффект искусственно, чтобы я мог протестировать наше программное обеспечение?
Если это имеет значение, приложение написано на C++/MFC с использованием классов CAsyncSocket.
Редактировать:
Я попытался использовать несуществующий хост, и я получаю ошибку сокета:
WSAEINVAL (10022) Неверный аргумент
Моей следующей попыткой было использовать предложение Александра подключиться к другому порту, например 81 (хотя на моем собственном сервере). Это сработало отлично. Точно так же, как потерянное соединение (ожидание 60 секунд, затем ошибка). Спасибо!
22 ответа
Подключитесь к существующему хосту, но к порту, заблокированному межсетевым экраном, который просто отбрасывает пакеты TCP SYN. Например, www.google.com:81.
Подключитесь к не маршрутизируемому IP-адресу, например 10.255.255.1.
Множество хороших ответов, но, похоже, самым чистым решением является эта услуга
http://httpstat.us/504?sleep=60000
Вы можете настроить продолжительность тайм-аута (до 230 секунд) и возможный код возврата.
Если вы работаете на Unix-машине, вы можете запустить прослушивание порта, используя netcat:
nc -l 8099
Затем измените ваш сервис так, чтобы он вызывал все, что обычно делает с этим портом, например, http://localhost:8099/some/sort/of/endpoint
Затем ваша служба откроет соединение и запишет данные, но никогда не получит ответ, и, таким образом, предоставит вам тайм-аут чтения (вместо отказа в соединении)
Следующий URL всегда дает время ожидания и объединяет лучшие ответы @Alexander и @Emu, приведенные выше:
С помощью example.com:81
является улучшением ответа Александра, потому что example.com зарезервирован стандартом DNS, поэтому он всегда будет недоступен, в отличие от google.com:81
, который может измениться, если Google захочет. Также из-за example.com
определен как недоступный, вы не будете наводнять серверы Google.
Я бы сказал, что это улучшение по сравнению с ответом @emu, потому что его намного легче запомнить.
10.0.0.0, 10.255.255.255, 172.16.0.0, 172.31.255.255, 192.168.0.0,192.168.255.255
все они не маршрутизируются.
Вы можете использовать Python REPL для имитации времени ожидания при получении данных (т. Е. После успешного установления соединения). Ничего, кроме стандартной установки Python не требуется.
Python 2.7.4 (default, Apr 6 2013, 19:54:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s.bind(('localhost', 9000))
>>> s.listen(0)
>>> (clientsocket, address) = s.accept()
Теперь он ждет входящего соединения. Подключите все, что вы хотите проверить localhost:9000
, Когда вы это сделаете, Python примет соединение и accept()
вернет это. Если вы не отправите какие-либо данные через clientsocket
сокет вызывающего абонента должен истечь во время следующего recv()
,
Я хотел бы обратить внимание всех на патод
С конфигом (взятым из их примеров) 200:b@100:dr
вы получите соединение, которое случайно падает.
Как насчет программного решения:
Установите SSH-сервер на сервер приложений. Затем используйте сокет туннеля для создания связи между вашим локальным портом и удаленным портом на сервере приложений. Вы можете использовать инструменты клиента ssh для этого. Вместо этого подключите ваше клиентское приложение к подключенному локальному порту. Затем вы можете разорвать туннель сокета по желанию, чтобы смоделировать время ожидания соединения.
Если вы хотите использовать активное соединение, вы также можете использовать http://httpbin.org/delay/, где # - время, которое вы хотите, чтобы их сервер ожидал перед отправкой ответа. Пока ваш тайм-аут короче задержки... должен имитировать эффект. Я успешно использовал его с пакетом запросов Python.
Возможно, вы захотите изменить свой запрос, если отправляете что-то деликатное - понятия не имею, что происходит с данными, отправленными им.
Доступны сервисы, которые позволяют искусственно создавать тайм-ауты для источника, вызывая API, где вы указываете, сколько времени потребуется серверу для ответа. Тайм-аут сервера на Macgyver является примером такой службы.
Например, если вы хотите протестировать запрос, ответ на который занимает 15 секунд, вы просто отправите запрос в API macgyver.
JSON Payload:
{
"timeout_length": 15000
}
Ответ API (через 15 секунд):
{
"response": "ok"
}
Программа Тайм-аут сервера на Macgyver
https://askmacgyver.com/explore/program/server-timeout/3U4s6g6u
Техника, которую я часто использую для симуляции времени ожидания случайного соединения, заключается в использовании переадресации локального порта ssh.
ssh -L 12345:realserver.com:80 localhost
Это будет перенаправлять трафик на localhost:12345 на realserver.com:80. Вы также можете сделать это на своем локальном компьютере, если хотите:
ssh -L 12345:localhost:8080 localhost
Таким образом, вы можете направить ваше приложение на локальный и пользовательский порт, и трафик будет перенаправлен на целевой хост: порт. Затем вы можете выйти из этой оболочки (вам также может понадобиться сочетание клавиш ctrl + c после выхода из нее), и это прекратит переадресацию, в результате чего ваше приложение увидит потерю соединения.
Вы можете установить драйвер Microsoft Loopback, который создаст для вас отдельный интерфейс. Затем вы можете подключиться к нему к какой-либо вашей службе (ваш собственный хост). Затем в Network Connections вы можете отключить / включить такой интерфейс...
Несмотря на то, что не совсем ясно, какой именно OP хочет проверить: есть разница между попыткой соединения с несуществующим хостом / портом и временем ожидания уже установленного соединения. Я пойду с Робом и подожду, пока соединение не заработает, а затем потяну за кабель. Или - для удобства - используйте виртуальную машину, работающую в качестве тестового сервера (с сетевым мостовым соединением), и просто деактивируйте интерфейс виртуальной сети после установления соединения.
Другой вариант — создать локальную конечную точку, которая возвращает отложенный ответ. Вы можете сделать это с помощью нескольких строк Python:
from flask import Flask
from time import sleep
app = Flask(__name__)
@app.route('/delayed', methods = ['POST'])
def delayed_request():
sleep(120) # delay response by 120 seconds
return {"msg": "completed"}
app.run(port = 5000)
Чтобы проверить это:
curl --request POST http://localhost:5000/delayed
Обратите внимание, что для этого требуется установка Flask в качестве зависимости (pip install flask
).
У меня были проблемы в том же духе, что и у вас. Чтобы проверить поведение программного обеспечения, я просто отключил сетевой кабель в соответствующее время. Я должен был установить точку останова прямо перед тем, как хотел отключить кабель.
Если бы я делал это снова, я бы вставил переключатель (нормально замкнутая кратковременная кнопка) в сетевой кабель.
Если физическое отключение вызывает другое поведение, вы можете подключить компьютер к дешевому концентратору и установить коммутатор, о котором я упоминал выше, между вашим концентратором и основной сетью.
- РЕДАКТИРОВАТЬ - во многих случаях вам потребуется работающее сетевое соединение, пока вы не достигнете определенной точки в своей программе, ТО затем вы захотите отключиться, используя одно из многих предложенных предложений.
Проще всего было бы разорвать ваше соединение с помощью CurrPorts.
Однако для модульного тестирования кода обработки исключений, возможно, вам следует рассмотреть возможность абстрагирования кода вашего сетевого подключения и написать заглушку, макет или декоратор, которые выдают исключения по требованию. После этого вы сможете протестировать логику обработки ошибок приложения без необходимости использовать сеть.
В прошлом я использовал несколько тактик для симуляции сетевых проблем;
- Вытащите сетевой кабель
- Выключите коммутатор (в идеале, когда коммутатор, к которому подключен компьютер, все еще находится под напряжением, чтобы машина поддерживала свое "сетевое соединение") между вашей машиной и "целевой" машиной
- Запустите программное обеспечение брандмауэра на целевой машине, которое автоматически отбрасывает полученные данные.
Одна из этих идей может дать вам некоторые средства для искусственного создания сценария, который вам нужен
В зависимости от того, какое программное обеспечение брандмауэра у вас установлено / доступно, вы должны иметь возможность заблокировать исходящий порт, а в зависимости от того, как настроен ваш брандмауэр, он должен просто отбросить пакет запроса подключения. Нет запроса на соединение, нет соединения, истекло время ожидания. Это, вероятно, сработало бы лучше, если бы оно было реализовано на уровне маршрутизатора (они склонны отбрасывать пакеты вместо отправки перезагрузок или чего-то подобного для ситуации), но обязательно найдется программный пакет, который тоже справился бы с этой задачей.
Для меня самым простым способом было добавить статический маршрут на офисный маршрутизатор на основе сети назначения. Просто перенаправьте трафик на не отвечающий хост (например, на ваш компьютер), и вы получите тайм-аут запроса.
Лучшим для меня было то, что статическим маршрутом можно управлять через веб-интерфейс и легко включать / отключать.
Вы можете попытаться подключиться к одному из известных веб-сайтов через порт, который может быть недоступен извне - например, 200. Большинство брандмауэров работают в режиме DROP, и он будет имитировать время ожидания для вас.
Подключите сетевой кабель к коммутатору, который не имеет других подключений / кабелей. Это должно работать имхо.