2016-04-16 10 views
1

Ich arbeite an einem Knotenprojekt, das elasticsearch verwendet. Meine Testkette ist Schluck, Mokka, Chai, Sinon. Ich habe Schwierigkeiten, meine Integrationstests konsistent zu machen. Ich möchte Beispieldaten in die Datenbank laden und dann einige Tests ausführen. Ich glaube, dass ich Probleme habe, weil die Dokumente, die ich lade, zu dem Zeitpunkt nicht indiziert sind, zu dem meine Tests, die sie benutzen, laufen.Wie gehe ich mit elasticsearchs Index-Timing um, wenn ich Integrationstests mit Mocha durchführe

Ich habe um das funktioniert durch folgende Maßnahmen:

before(function (done) { 
     testData.simpleLoadData(100, 2000); 
     setTimeout(function() { 
      done(); 
     }, 5000); 
    }); 

Dies funktioniert vor Ort in Ordnung, es funktioniert gelegentlich auf travis. Wenn ich den Timer auf 10000 hochsetze, funktioniert es im Allgemeinen an beiden Orten.

Gibt es einen Weg dazu, ohne auf setTimeouts im Testcode zurückgreifen zu müssen? Der manuelle Umgang mit dem Timing macht mich etwas zimperlich.

Ist manuell mit Zeitüberschreitungen die beste Option, die ich habe oder gibt es bessere Möglichkeiten?

Hinweis: Dies sind Integrationstests und ich möchte explizit die externen Abhängigkeiten verwenden. Ich habe Komponententests, die nicht auf die Datenbank angewiesen sind.

Antwort

1

Es gibt zwei Dinge, die Sie stolpern können: Shard Allocation und Refresh-Zyklen.

Die erste kann passieren, wenn Sie einen neuen Index erstellen. Die Create Index API gibt 200 OK zurück, sobald der Master die Anfrage bestätigt und den Erstellungsprozess beginnt. Die eigentliche Shard-Zuweisung erfolgt jedoch asynchron im Hintergrund. Und während es schnell geht, können Integrationstests manchmal ausgeführt werden, bevor der Index vollständig ausgeführt wird und beim Versuch, Dokumente zu indizieren, einen Fehler verursacht.

Die einfachste Möglichkeit, dies robust zu machen, besteht darin, den Index zu erstellen und dann Health API mit wait_for_status=green aufzurufen (oder gelb, je nachdem, ob Sie Replikate verwenden). Dieser Anruf wird blockiert, bis der Index vollständig zugewiesen ist.

Das nächste Problem bezieht sich auf den Fast-Echtzeit-Aspekt der Suche. Standardmäßig aktualisiert Elasticsearch den Suchindex jede Sekunde. Dies kann für Integrationstests zu langsam sein, und Ihre Dokumente werden möglicherweise indexiert, können aber nicht durchsucht werden, wenn Ihre Tests ausgeführt werden.

Um dies zu beheben, indizieren Sie alle Ihre Dokumente und rufen Sie dann Refresh API auf dem Zielindex. Sobald dieser Anruf zurückkehrt, sind Ihre Dokumente "live" und durchsuchbar.

+0

so wird die Aktualisierung blockiert bis abgeschlossen? Ich habe meinem Speicherobjekt gerade eine Aktualisierungsmethode hinzugefügt, um damit herumzuspielen. Danke, ich werde mich heute Nacht damit herumschlagen und berichten. – skarface

+1

@skarfa yep, es wird blockieren! :) – Zach

+0

relevanten Code hier: http://pastebin.com/9GVWptpN Daten scheinen nicht verfügbar sein, nachdem RefreshIndices abgeschlossen ist. Immer noch ziemlich neu für den Knoten, Entschuldigung, wenn ich etwas Grundlegendes vermisse – skarface

Verwandte Themen