Как правильно имитировать высокую задержку при тестировании сервера с сокетом C #? - PullRequest
5 голосов
/ 09 июля 2010

У меня есть класс, который использует 'System.Net.Sockets.Socket' напрямую для связи по сети, и в настоящее время я использую следующие два интерфейса для разрыва зависимости от класса Socket:

public interface ISocketListener
    {
        void Listen(int backlog);

        ISocket Accept();

        void Bind(EndPoint endpoint);               
    }

public interface ISocket
    {
        void Connect (EndPoint ep);

        Stream CommunicationStream { get; }

        void Close();

        void Close(int timeout);

        void Shutdown();
    }

ВПроизводственная реализация Я просто перенаправляю все вызовы методов на закрытый объект Socket.В тестовой среде я использую MemoryStream как канал связи между сокетами.Поскольку у меня мало опыта в этой области, при написании тестов у меня возникли некоторые вопросы: существуют ли «формальные» передовые практики при тестировании такого рода программного обеспечения?При тестировании интеграции, как я могу проверить производительность этого сервера в нескольких соединениях / ситуациях с высокой задержкой (более конкретно, как имитировать эти ситуации)?Почему существуют асинхронные версии Socket.Accept / Socket.Receive?Можно ли заменить асинхронные методы для обработки их синхронных версий в отдельных потоках?

Ответы [ 3 ]

1 голос
/ 09 июля 2010

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

1 голос
/ 09 июля 2010

Я не знаком с объектом сокета. Тем не менее, я провел некоторые исследования о тестировании. Похоже, вы на правильном пути. Написание интерфейсов, которые могут ссылаться на фактические объекты, которые будут использоваться в производственных или тестовых объектах, обычно считается хорошей практикой. Этот шаблон известен как «Внедрение зависимостей».

Я не знаю, как работает сокет, но то, что вы можете сделать для целей тестирования, - это создать новый тестовый объект для использования вместо сокета, который вы хотите протестировать. Этот тестовый объект может просто вызвать Thread.Sleep(x) для добавления некоторой имитированной задержки перед возвратом данных.

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

0 голосов
/ 09 июля 2010

Существуют ли «формальные» передовые практики? в тестировании такого рода программного обеспечения?

Я могу поговорить об этом, но я уверен, что здесь есть какая-то полезная информация о стеке или о дикой природе.

При проведении интеграционного тестирования, как я могу проверить производительность этого сервер в нескольких подключениях / высокий латентные ситуации (более конкретно, как смоделировать эти ситуации)?

Для простого начала напишите несколько процедур тестирования и регистрации, запустив их в отдельном блоке, который забивал сервер множеством запросов ... включая бессмысленные. Запуск log4net на обоих также был бы полезен. Как уже было сказано, можно ввести некоторую задержку через своего рода прокси ... ящик, который находится между клиентом и сервером. Клиент указывает на прокси-сервер, и прокси-сервер изменяет данные ... задержку, изменение порядка пакетов и т. Д. ... отправку на сервер ... в обратном порядке и повторите. Немного в стороне ... Я бы избегал Thread.Sleep (...). Лучше использовать что-то вроде этого:

lock (timelock) { Monitor.Wait(timelock, TimeoutInMilliseconds); }

... асинхронные версии Socket.Accept / Socket.Receive? Могу я заменить асинхронные методы для обрабатывая их синхронные версии в отдельные темы?

У вас есть много опций, асинхронные методы, обычные старые потоки, пул потоков, TPL и т. Д. Лучший выбор зависит от приложения.

Вот пример асинхронного сокета сервера из записи MSDN для сокетов .

По счастливой случайности ... Книга О'Рейли: C # 4.0 в двух словах имеет превосходный набор примеров TCP-сервера , которые охватывают как асинхронные, так и потоковые методы. в блокирующих / неблокирующих проявлениях. Вот один из примеров ....

  public class Server
  {
    public void Serve(IPAddress address, int port)
    {

      TcpListener listener = new TcpListener(address, port);
      listener.Start();
      while (true)
      {
        TcpClient c = listener.AcceptTcpClient();
        Task.Factory.StartNew(Accept, c);
      }
    }

    void Accept(object clientObject)
    {
      using (TcpClient client = (TcpClient)clientObject)
      {
        using (NetworkStream n = client.GetStream())
        {
          byte[] data = new byte[5000];

          int bytesRead = 0; int chunkSize = 1;

          while (bytesRead < data.Length && chunkSize > 0)
          {
            bytesRead +=
              chunkSize = n.Read /// Read is blocking
                (data, bytesRead, data.Length - bytesRead);
          }

          Array.Reverse(data);
          n.Write                /// Write is blocking
            (data, 0, data.Length);
        }
      }
    }
  }

Надеюсь, это полезно.

P.S. Получить копию C # 4.0 в двух словах ... это хорошо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...