2010-07-09 7 views
5

Ho una classe che utilizza 'System.Net.Sockets.Socket' direttamente per comunicazione di rete, e attualmente utilizzate le seguenti due interfacce di rompere dipendenza dalla classe Socket:Come simulare correttamente una latenza elevata su un test del server socket C#?

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(); 
    } 

Nell'attuazione I produzione basta reindirizzare tutte le chiamate di metodo all'oggetto Socket privato. Nell'ambiente di test, utilizzo un MemoryStream come "tubo" di comunicazione tra gli zoccoli. Dato che ho poca esperienza in materia, alcune domande mi sono apparse nella testa mentre scrivevo test: ci sono buone pratiche "formali" per testare questo tipo di software? Durante i test di integrazione, come posso testare le prestazioni di questo server in più connessioni/situazioni di latenza elevata (in particolare, come simulare queste situazioni)? Perché esistono versioni asincrone di Socket.Accept/Socket.Receive? Posso sostituire i metodi asincroni per gestire le loro versioni sincrone in thread separati?

risposta

0

Esistono buone pratiche "formali" per testare questo tipo di software?

Posso parlare con questo ma sono sicuro che ci sono alcune buone informazioni qui in pila o fuori in natura.

Quando fare test di integrazione, come faccio a testare le prestazioni di questo server a connessioni multiple/alti situazioni latenza (più specificamente, come simulare queste situazioni)?

Per iniziare in modo semplice, scrivere alcune routine di test e registrazione, eseguendole su una casella separata, che ha martellato il server con una serie di richieste ... comprese quelle prive di senso. Anche l'esecuzione di log4net su entrambi sarebbe utile. L'introduzione di un certo ritardo potrebbe essere fatto, come già accennato, tramite una sorta di proxy ... una scatola che si trova tra il client e il server. Il client punta al proxy e il proxy modifica i dati ... ritardo, modifica ordine dei pacchetti, ecc .... invia al server ... invertire e ripetere. Per quanto mi riguarda, vorrei evitare Thread.Sleep (...). Meglio usare qualcosa di simile:

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

...versioni asincrone di Socket.Accept/Socket.Receive? Posso sostituire i metodi asincroni per gestendo le loro versioni sincrone nei thread separati ?

si hanno molte opzioni, metodi asincroni, pianura vecchio filettatura, ThreadPool, il TPL, ecc La scelta migliore è l'applicazione specifica.

Questo è un Asynchronous Server Socket Example dalla voce MSDN su sockets.

Per fortuna avrebbe voluto ... il libro O'Reilly: C# 4.0 in a Nutshell ha un eccellente set di TCP Server examples che copre sia i metodi asincroni/filettati nelle manifestazioni bloccanti/non bloccanti. Ecco uno degli esempi ....

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); 
     } 
     } 
    } 
    } 

Spero che questo sia utile.

P.S. Ottenere una copia di C# 4.0 in a Nutshell ... è buona.

+0

Grazie per i suggerimenti, darò un'occhiata al libro. Penso che impostare un'altra macchina solo per fare alcuni test di integrazione sia un po 'eccessivo. Voglio che i test siano veloci e li eseguiamo tutti premendo un pulsante –

+0

Puoi certamente fare i tuoi test dalla stessa casella..ma.. poi condividerai lo stesso stack di rete. Quindi i risultati saranno leggermente distorti. Non è un rompicapo, dovresti solo essere consapevole dei possibili effetti collaterali ... divertiti. – Rusty

1

Non ho familiarità con l'oggetto socket. Tuttavia, ho fatto qualche ricerca sui test. Sembra che tu sia sulla strada giusta. Le interfacce di scrittura che possono riferirsi sia agli oggetti reali che verranno utilizzati negli oggetti di produzione o di prova sono generalmente considerate una buona pratica. Questo modello è noto come "Iniezione di dipendenza".

Non so come funziona il socket, ma ciò che è possibile fare a scopo di test è creare un nuovo oggetto di test da utilizzare al posto del socket che si desidera testare. Questo oggetto di prova può semplicemente chiamare Thread.Sleep(x) per aggiungere una certa latenza simulata prima di restituire i dati.

Modifica: Vorrei anche precisare che dovrete fare molta attenzione ad accertare esattamente dove si verifica la latenza di rete nel vostro codice in modo che quando si inietta la latenza artificiale, si aggiunga a lo stesso posto nel codice in cui si verificherebbe nel mondo reale.

+0

Intendi dividere alcuni dati binari in blocchi e inviare ogni blocco utilizzando intervalli Thread.Sleep? Questa è una possibile soluzione, ma non sono sicuro che se simuli un'alta latenza corretta, potrei fare un tentativo. Che dire della gestione di più connessioni simultanee? come sarebbe gestito? –

+0

Quello che sto dicendo è che, dal momento che hai scritto la tua interfaccia, dovresti essere in grado di scrivere un oggetto test che simula la latenza e usarlo nell'ambiente di test. Non posso dire nulla dei dettagli di come dovrebbe essere simulata la latenza. –

1

È possibile simulare un'elevata latenza creando un server proxy da inserire tra la propria connessione, quindi è possibile aggiungere un ritardo durante il nuovo invio dei dati.

+0

Intendi un server proxy deriso? Potresti fare un esempio? –

Problemi correlati