Domanda

In questo asp.net sto ripulendo è possibile che si verifichino deadlock. Voglio assicurarmi che il codice li gestisca correttamente, quindi sto provando a scrivere test NUnit che attivano un deadlock .....

Il DAO è diviso per entità. Ogni entità ha una serie di test che sono circondati dai metodi Startup () e Teardown () che creano un ambito di transazione e quindi lo fanno tornare indietro al termine dei test. Funziona benissimo per tutto il resto, ma è completamente inutile per i deadlock.

Come posso configurare ed eseguire un "deadlock"? test usando TransactionScope e SQL2000 (ovvero MSDTC è coinvolto) che possono essere riprodotti in modo affidabile? Più in dettaglio: so che esiste una situazione in cui due utenti chiamano due funzioni con valori di dati diversi e specifici, quindi un deadlock può . Come posso simulare questo all'interno di NUNIT - e far sì che il deadlock accada sempre ?

E sì, ho iniziato con il " Perché non fermi i deadlock che si verificano in primo luogo " piano d'azione, ma non ho alcun controllo sul codice in cui possono verificarsi i deadlock: chiamo solo le funzioni e possono deadlock.

È stato utile?

Soluzione

Se il deadlock comporta il lancio di un'eccezione, si desidera utilizzare un oggetto simulato per emulare l'eccezione generata.

L'idea di base è che dici al tuo framework Mock Object (mi piace TypeMock ) di lanciare un'eccezione invece, qualcosa del genere:

MockObject mo = MockManager.MockObject(typeof(MyDeadlockException));
mock.ExpectAndThrow("MyMethod", (MyDeadlockException)mo.Object); 

L'idea è sostanzialmente la stessa per altri framework beffardi.

Altri suggerimenti

La maggior parte di queste soluzioni coinvolge più thread. Eccone uno che non lo fa.

Chiudere queste lacune - Riprodurre errori del database

L'autore è Alex Kuznetsov.

Che cosa succede se uno dei tuoi test nel mezzo della tua transazione fa solo un " wait " per circa 5 minuti? In alternativa, si scrive semplicemente un test che avvia una transazione, crea un nuovo record e quindi aggiorna quel record senza impegnarsi. Quindi, avvia una nuova transazione e prova a leggere quel record che è stato creato e che è attualmente in fase di aggiornamento. Avrai un punto morto lì.

Che cosa succede se si blocca manualmente un tavolo e lo si lascia SEMPRE bloccato? Quindi, qualsiasi azione tu abbia intrapreso contro quel tavolo produrrebbe una situazione di deadlock?

Venendo a questo punto cieco, ma è possibile nel metodo TestSetup creare effettivamente una connessione SQLC al database? Quindi, usando quello, potresti semplicemente emettere un comando per bloccare la tabella o intraprendere qualche azione per bloccare un record o una pagina? In questo modo sarebbe al di fuori di qualsiasi altra transazione in corso? Sembra che questa sarebbe un'opzione che hai già considerato però. Cosa mi manca della tua situazione?

Per i test unitari probabilmente si desidera evitare di utilizzare effettivamente un database. Come fai a sapere che hai un punto morto. Dovresti testare la condizione che ti dice che c'è un deadlock e crearlo nel tuo test.

Una simulazione è l'ideale per imitare questo se si chiama un servizio e restituisce un errore. Basta che il finto restituisca l'errore che ci si aspetta. Se stai aspettando un timeout o qualcosa del genere, si applica la stessa cosa.

In generale, un test unitario deve essere eseguito solo sul codice testato e non fare affidamento su altri codici o componenti. Detto questo - i database sono essenzialmente un altro componente e probabilmente stai facendo una sorta di test funzionali usando nunit per guidarli.

In tal caso, è necessario creare una situazione di deadlock ma bloccare un record o una tabella e quindi chiamare un componente che tenta di utilizzare lo stesso record e gestire la risposta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top