cppmm 26.06.2009 23:15
Coding — Тестируем клиент-серверный софт.
Иногда бывают ситуации, когда надо увидеть, что же на самом деле происходит между клиентом и сервером. Т.е. увидеть, о чём и как они разговаривают. Конечно, всегда есть tcpdump, но иногда его не хватает(или он не совсем удобен). Например, если надо подробно увидеть все передаваемые данные в нормальном, понятном человеку виде. Вот, например, недавно я видел, что клиент серверу запрос отправил, а вместо ответа получает какую-то ерунду. Потом, после очередного ковыряния конфигов, было видно, что сервер отвечает нормально, но теперь уже клиент непонятно что сыпет.Ну или другой пример - пишете вы своё небольшое клиент-серверное приложение, общающиеся по своему протоколу, но вот что-то как-то не выходит общение.
В таких случаях одним из вариантов тестирования может быть написание простенького фейкового сервера. Простой пример подробного я и опишу.
Представим такую абстрактную ситуацию: сервер, слушающий порт 3333 и клиент, что-то у этого сервера спрашивающий. После tcpdump'а стало видно, что после очередного запроса, клиент ждёт какого-то ответа, но вместо этого получает сообщение об ошибке от сервера(tcpdump -ntvvvXpi). Кто виноват - неясно. То ли клиент неправильный запрос шлёт, то ли сервер неправильно на него отвечает. Разбираться в исходниках клиента и сервера нет ни времени, ни желания(а зачастую и знаний, потому как чёрт его знает, чего там разработчики напридумывают), поэтому сделаем хитрый манёвр - напишем простейший сервер, выполняющий минимум запросов и посмотрим, что же нам говорит на это клиент. В качестве языка я выбрал perl, потому как это perl, а всё остальное неправославно. :)
Ну а теперь подробнее. Инициализацию сервера, буферизацию и подробные особенности perl'а описывать смысла нет - это всё есть в документации(пакет perl-doc). Переходим сразу к делу. Наш импровизированный сервер висит на интерфейсе и слушает всё, что туда приходит. Всё, что можно, он складывает в лог, но если получает запрос "client-request", то отвечает на него так, как ожидает клиент. Т.е. вместо client-request мы подставляем запрос, на котором затыкается общение клиента с сервером. Скрипт, видит его и отвечает на него так, как нужно клиенту, чтобы общение продолжалось. Следующий запрос клиента складывается в лог. Информация собрана.
После этого любимым текстовым редактором открываем лог и читаем, что же там наговорили наши клиенты с сервером. Находим строки, связанные с проблемным запросом и смотрим, правильно ли ответил клиент на него, или нет. Если правильно, то значит проблема в сервере и начинаем ковырять его, если же нет, то мучаем настройки клиента.
Вот, собственно и всё.
Разумеется, я выложил самый простой пример. В реальных условиях скрипт дополняется несколькими запросами. Иногда даже приходится целый диалог организовывать, чтобы найти ошибку. Но организация подобного диалога по сути - обычная копипаста внутри скрипта. Это значительно проще, чем лопатить километровые конфиги или разбираться в чужих исходниках. Зная же точно, где происходит затык, найти ошибку уже проще.
Т.е. это не рабочий пример, а просто описание одного из способов тестирования ПО.
sdvn 26.06.2009 23:46 #
+ 0 -
А может просто сразу стоит слушать через тот же Ethereal с дешифровкой пакетов? Ничего писать не придется, и сразу поможет понять где ошибка.
Слушать можно. Но иногда некоторые ошибки можно выявить только после некоторого диалога. Простой пример: если просто слушать 25-ый порт, нельзя проверить работоспособность почтового клиента, потому что пока клиент не получит ответа на приветствие(helo или ehlo), он не начнёт аутентификацию и собственно пересылку почты. Цель этого подхода как раз "заставить говорить".
Это называется "юнит-тест", который обязан провести программист. На мой взгляд ничего нового сей пост в ряды программистов не принес.
Если сервер с клиентом договориться не могут, то запросы от клиента получить не трудно тем же tcpdump, а вот что должен отвечать сервер нужно где-то узнавать. Какие есть варианты?
после непродолжительного раздумья.
В документации к клиенту, в разделе "поддерживаемые ответы"?
В документации к клиенту, в разделе "поддерживаемые ответы"?
Зависит от клиента.
Но определённо в документации.
К примеру, когда приходилось тестировать swf-флешку, она высылала запрос вида: <policy-file-request/> и ожидала в ответ файл crossdomain.xml одной строкой.
Ну или другой вариант - в описании протокола. Взять ту же почту. Там вполне определённый набор команд и чётка последовательность (helo, ответ, mail from:<>, ответ и т.д.).
Но определённо в документации.
К примеру, когда приходилось тестировать swf-флешку, она высылала запрос вида: <policy-file-request/> и ожидала в ответ файл crossdomain.xml одной строкой.
Ну или другой вариант - в описании протокола. Взять ту же почту. Там вполне определённый набор команд и чётка последовательность (helo, ответ, mail from:<>, ответ и т.д.).