Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Solr-Support for the testserver #5804

Open
wants to merge 3 commits into
base: master
from

Conversation

Projects
None yet
2 participants
@jone
Copy link
Member

commented Jul 9, 2019

🚧 Bitte nicht mergen; allenfalls kommen noch Ergänzungen 🚧

Ziel

Der Testserver bietet Drittanwendungen und dem neuen UI die Möglichkeit, Tests gegen ein isolierbares aber möglichst vollständiges GEVER auszuführen. Bislang hatte der Testserver noch keine Unterstützung.

Fürs Produkt RIS wird Solr nun eine wichtige Komponente, da wir über die GEVER-API @solrsearch nun Solr-Abfragen ausführen möchten. Damit dies in den Tests von RIS abgebildet werden kann benötigen wir daher von RIS her im Testserver vollwertige Solr-Unterstützung inkl. Isolation.

Change

Der Testserver startet neu ein Solr Server inkl. Isolation der Datenbank. Dies ermöglicht die Nutzung von Solr-Features, wie z.B. den @solrsearch API Endpoint.

Dazu wird ein zusätzlicher Solr-Core testserver konfiguriert, welcher jeweils geleert und wieder verwendet wird. Pro Buildout-Pfad kann daher nur ein Testserver gleichzeitig laufen. Der Solr-Core muss zu Buildout-Zeit erstellt werden.

SolrServer
Die SolrServer Klasse ist Zuständig für den Betrieb des Solr-Servers und wird im Testserver-Prozess genutzt. SolrServer ist ein Singleton, das den Solr-Server mit Hilfe eines Threads in einem Subprozess laufen lässt. Das Stoppen des Prozesses wurde möglichst zuverlässig implementiert (atexit-Hook).

SolrReplicationAPIClient
Der SolrReplicationAPIClient ermöglicht es, vom Solr-Core ein Backup zu erstellen, das später wieder geladen werden kann. Weiter kann er den Solr-Core leeren.
Beim Erstellen des Backups ist es wichtig, zuerst mit einem commit=true-Update das Schreiben auf die Disk auszulösen; ansonsten können Backups unvollständig sein.
Das Backup kann benannt werden, so dass der Client auch für ander Zwecke als den Testserver verwendet werden kann.

Testserver
Im Moment wird Solr direkt im Testserver-Layer eingebaut. Dies ermöglicht es uns, diesen Teil bereits zu nutzen. Jedoch wurden die Komponenten so aufgebaut, dass sie später gut auch in anderen Tests (z.B. Integrationstests) verwendet werden können.
Der Selftest wurde ergänzt, so dass die Solr-Isolation via @solrsearch-Endpoint getestet wird.

Design und Grundsätze

  • Der Solr-Core wird immer beim Starten des Testservers geleert und kann grundsätzlich Artefakte eines früheren Prozesses enthalten.
  • Nach dem Test-Setup wird einmalig ein Backup erstellt; dieses wird dann jeweils zwischen den Tests wieder restored.
  • Ports können grundsätzlich über Umgebungsvariabeln gesetzt werden (daher auch Update auf 4teamwork/ftw.recipe.solr#7).

Checkliste

  • Gibt es neue Funktionalität mit einem Dokument? Funktioniert das auch mit einem Mail?
  • Wurde etwas an der Aufgabe angepasst? Funktioniert das auch mit einer Weiterleitung?
  • Profil angepasst? Sind UpgradeSteps vorhanden/nötig?:
  • Sind UpgradeSteps deferrable, oder können gewisse Schritte des Upgrades konditional ausgeführt werden?
  • Gibts es eine DB-Schema Migration?
    • Wurde alle Columns/Änderungen aus dem Modell in einer DB-Schema Migration nachgeführt.
    • Sind Constraint-Namen maximal 30 Zeichen lang (Oracle)?
  • Gibt es ein neues Feature-Flag? Wurden dafür Tests mit aktiviertem und deaktivierte Flag geschrieben?
  • Könnten Kundeninstallationen von den Änderungen betroffen sein? Müssen Policies angepasst werden?
  • Gibt es neue Übersetzungen?
    • Sind alle msg-Strings in Übersetzungen Unicode?
    • Wird die richtige i18n-domain verwendet (Copy-Paste Fehler sind hier häufig)?
  • Wenn bei Schema-definitionen missing_value spezifiziert ist muss immer auch default auf den gleichen Wert gesetzt werden
  • Changelog-Eintrag vorhanden/nötig?
  • Aktualisierung Dokumentation vorhanden/nötig?
Setup a Solr server in the testserver.
Let the testserver start, stop and manage a Solr server.
The solr server is configured properly and is isolated with the Solr
backup feature.

@jone jone requested a review from 4teamwork/gever Jul 9, 2019

@jone jone changed the title Setup a Solr server in the testserver. Add Solr-Support for the testserver Jul 9, 2019

@jone

This comment has been minimized.

Copy link
Member Author

commented Jul 10, 2019

Backport für 2019.3-stable in #5805.

def create_object(self):
obj = super(DocumentBuilder, self).create_object()
# Trigger bumblebee checksum creation:
notify(ObjectAddedEvent(obj))

This comment has been minimized.

Copy link
@jone

jone Jul 11, 2019

Author Member

Ich habe das Problem festgestellt, dass über die API bei Dokumenten keine Checksumme ausgeliefert wird. Irgendwie wird die Checksumme nicht sauber indiziert.

Auf Seite Bumblebee ist die Indexierung aber in einem added event subscriber. Daher hab ich das mal hier hinzugefügt.

Das komisch ist, dass wir integration tests haben, bei denen die Checksumme da ist.

Dieser Change bewirkt nun das Tests failen (weil mehr Journal-Einträge).
Mir ist unklar was hier die korrekte lösung ist.

@lukasgraf
Copy link
Member

left a comment

Preliminary review - I'm still looking into the Bumblebee stuff.

LGTM 👍, apart from a few comments.

@@ -1039,6 +1039,7 @@ The ports used by the testserver can easily be changed through environment varia

- ``ZSERVER_PORT`` - the port of the GEVER http server (default: ``55001``)
- ``TESTSERVER_CTL_PORT`` - the port of the XMLRPC control server (default: ``55002``).
- ``SOLR_PORT`` - the port of the Solr server which is controlled by the tesserver (default: ``55003``).

This comment has been minimized.

Copy link
@lukasgraf

lukasgraf Jul 11, 2019

Member

tesserver -> testserver

except KeyboardInterrupt:
pass
except OSError as exc:
if exc.strerror != 'No such process':

This comment has been minimized.

Copy link
@lukasgraf

lukasgraf Jul 11, 2019

Member

Detail: Comparing exc.errno against the respective constant from the errno module would be a bit cleaner.

if backup_path.exists():
backup_path.rmtree()

# First, trigger solr commit so that changes are writte to disk.

This comment has been minimized.

Copy link
@lukasgraf

lukasgraf Jul 11, 2019

Member

writte -> written

return response

def restore_backup(self, name):
"""Restore a backup. `name` refers to the snapshot name.

This comment has been minimized.

Copy link
@lukasgraf

lukasgraf Jul 11, 2019

Member

snapshot name -> backup name
I think we can eliminate the bak- prefixing as well, and then simply refer to it as backup_name everywhere.


def _require_configured(self):
if not self._configured:
raise ValueError('Configure first with SolrServer.get_instance().configure()')

This comment has been minimized.

Copy link
@lukasgraf

lukasgraf Jul 11, 2019

Member

SolrServer -> SolrReplicationAPIClient


package-name = opengever.core
package-namespace = opengever
test-egg = opengever.core[api, tests]

solr-core-name = testing

This comment has been minimized.

Copy link
@lukasgraf

lukasgraf Jul 11, 2019

Member

I'm slightly confused as to why we need the testing core (in addition to the testserver core).

For how development.cfg behaves it makes sense: You get two cores, development and testserver. One is for actually booting bin/instance fg, and one is to be used with bin/testserver (locally, during development).

But what do we need the testing one for in the base-plone-4.3.x.cfg?


if __name__ == '__main__':
# selftest:
# ./bin/zopepy opengever/core/solr_testing.py

This comment has been minimized.

Copy link
@lukasgraf

lukasgraf Jul 11, 2019

Member

This (bin/zopepy opengever/core/solr_testing.py, using development.cfg) currently gives me

Traceback (most recent call last):
  File "bin/zopepy", line 444, in <module>
    exec(compile(__file__f.read(), __file__, "exec"))
  File "opengever/core/solr_testing.py", line 241, in <module>
    server = SolrServer.get_instance().configure(port)
TypeError: configure() takes exactly 3 arguments (2 given)

(The SolrServer configure(port) below is missing core)

return response.json()

def create_backup(self, name):
"""Create a backup of the snapshot state identified by `name`.

This comment has been minimized.

Copy link
@lukasgraf

lukasgraf Jul 11, 2019

Member

This doesn't quite reflect any more what this method does. As far as I can tell, we don't use the intermediate snapshots (tags) any more. Thefore name is only used to specify the name the backup should get.


def testTearDown(self):
self.context_manager.__exit__(None, None, None)
SolrReplicationAPIClient.get_instance().restore_backup('fixture')

This comment has been minimized.

Copy link
@lukasgraf

lukasgraf Jul 11, 2019

Member

Is this for performance reasons (to kick off the restore already during the testTearDown , so it's probably already during the next testSetUp?

self.assertDictContainsSubset = case.assertDictContainsSubset

def __call__(self):
os.environ['ZSERVER_PORT'] = '0'
os.environ['TESTSERVER_CTL_PORT'] = '0'
os.environ['PYTHONUNBUFFERED'] = 'true'
os.environ['SOLR_PORT'] = os.environ.get('PORT3', '19903')

This comment has been minimized.

Copy link
@lukasgraf

lukasgraf Jul 11, 2019

Member

Hmm, why yet another default port here?

Make bumblebee access tokens predictable.
Use static bumblebee user salts in the testserver for having
predictable access tokens.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.