Zufälliger Fehler beim Testen mit NHibernate auf einer In-Memory SQLite-Datenbank

8

Ich habe ein System, das nach Erhalt einer Nachricht - es in eine Warteschlange stellt (in eine Tabelle schreibt), und ein anderer Prozess fragt die Datenbank ab und entfernt sie für die Verarbeitung. In meinen automatischen Tests habe ich die Operationen im selben Prozess zusammengeführt, kann aber (konzeptionell) die NH-Sitzungen nicht mit den beiden Operationen zusammenführen.

Natürlich - Probleme entstehen.

Ich habe alles gelesen, ich könnte die SQLite-InMemory-NHibernate Kombination über immer in der Test Welt zu arbeiten, aber ich habe laufe jetzt in ZUFALL vorgeschriebenen Prüfungen nicht wegen „keine solchen Tabelle“ Fehler. Um es klar zu machen - "zufällig" bedeutet, dass derselbe Test mit der gleichen genauen Konfiguration und dem gleichen Code manchmal fehlschlägt.

Ich habe die folgende SQLite-Konfiguration:

%Vor%

Zu Beginn meines Tests (bei jedem Test) hole ich den "statischen" Session-Provider und bitte ihn, die vorhandene DB zu bereinigen und das Schema neu zu erstellen:

%Vor%

Also, es ist in einer anderen Sitzung, aber die Verbindung ist in SQLite gepoolt, so dass die nächste Sitzung, die ich erstelle, das generierte Schema sieht. Doch während die meisten der Zeit es funktioniert - manchmal die später „enqueue“ Operation fehl, weil es nicht eine Tabelle für meine eingehenden Nachrichten sehen können. Auch - das scheint bei maximal einem oder zwei Mal pro Testsuite zu passieren; nicht alle Tests versagen, nur die erste (und manchmal ein anderer. Nicht ganz sicher, ob es die zweite oder nicht ist).

Der schlimmste Teil ist natürlich die Zufälligkeit. Ich habe mir gesagt, dass ich das jetzt schon mehrere Male behoben habe, nur weil es einfach "aufgehört hat zu versagen". Zufällig.

Dies geschieht auf FW4.0, System.Data.SQLite x86-Version, Win7 64b und 2008R2 (drei differen Maschine insgesamt), NH2.1.2, konfiguriert, um mit FNH, auf TestDriven.NET 32b präzediert und NUnit Konsole 32b Prozesse.

Hilfe?

    
Arielr 14.04.2011, 11:57
quelle

2 Antworten

8

Hi Ich bin mir ziemlich sicher, dass ich genau das gleiche Problem habe wie du. Ich öffne und schließe mehrere Sitzungen pro Integrationstest. Nachdem ich das SQLite Connection Pooling und einige eigene Experimente durchgegraben habe, bin ich zu folgendem Schluss gekommen:

Der SQLite-Pooling-Code speichert die Verbindung mit WeakReferences, was nicht die beste Option ist zum Zwischenspeichern, da der Verweis auf die Verbindung (en) gelöscht wird, wenn kein normaler (starker) Verweis auf die Verbindung vorhanden ist und der GC ausgeführt wird. Da Sie nicht vorhersagen können, wann der GC läuft, erklärt dies die "Zufälligkeit". Versuchen Sie, und fügen Sie ein GC.Collect(); zwischen einem Schließen und Öffnen einer anderen Sitzung, Ihre Prüfung wird immer fehlschlagen.

Meine Lösung bestand darin, die Verbindung zwischen den Eröffnungssitzungen wie folgt zwischenzuspeichern:

%Vor%

Jeder meiner Integrationstests erbt von dieser Klasse und ruft OpenSession () auf, um eine Sitzung abzurufen. RecreateDB wird von NUnit vor jedem Test wegen des Attributs [SetUp] aufgerufen.

Ich hoffe, das hilft Ihnen oder anderen, die diesen Fehler bekommen.

    
dvdvorle 05.01.2012, 14:55
quelle
0

Nur eine Sache, die Ihnen in den Sinn kommt, dass Sie die Sitzung nach dem Test nach dem Zufallsprinzip verlassen. Sie müssen sicherstellen, dass eine vorhandene ISession geschlossen ist, bevor Sie eine andere öffnen. Wenn Sie die using () -Anweisung nicht verwenden oder Dispose () manuell aufrufen, ist die Sitzung möglicherweise noch am Leben und verursacht diese zufälligen Ausnahmen.

    
Toni Parviainen 21.12.2011 17:25
quelle