-
Notifications
You must be signed in to change notification settings - Fork 443
Clear the functests search index when clearing the DB #9638
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
Conversation
558895f
to
52667ae
Compare
# Push all changes to segments to make sure all annotations that were added get removed. | ||
elasticsearch_dsl.Index(client.index, using=client.conn).refresh() | ||
|
||
client.conn.delete_by_query( | ||
index=client.index, | ||
body={"query": {"match_all": {}}}, | ||
# This query occasionally fails with a version conflict. | ||
# Forcing the deletion resolves the issue, but the exact | ||
# cause of the version conflict has not been found yet. | ||
conflicts="proceed", | ||
# Add refresh to make deletion changes show up in search results. | ||
refresh=True, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The global es_client
fixture (common to both unittests and functests) no longer clears the Elasticsearch index after each test. This has been moved into a unittests-only fixture.
@@ -51,7 +52,18 @@ def reset_app(app): | |||
|
|||
|
|||
@pytest.fixture | |||
def with_clean_db(db_engine): | |||
def with_clean_db_and_search_index(db_engine, clear_search_index): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The with_clean_db()
functests fixture has been replaced with a with_clean_db_and_search_index()
fixture: it doesn't make sense for a test to request a clean DB but not a clean search index. You can only have neither or both, not one without the other.
# Always unconditionally wipe the Elasticsearch index after every functional | ||
# test. | ||
@pytest.fixture(autouse=True) | ||
def always_delete_all_elasticsearch_documents(): | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed in another PR (#9636, which I'm not planning to merge) this fixture is broken and doesn't do anything. The functionality that this fixture was supposed to provide has been moved into the with_clean_db_and_search_index
fixture and is executed only for tests that use that fixure, not for every test.
@pytest.fixture | ||
def es_client(es_client, clear_search_index): | ||
yield es_client | ||
clear_search_index() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This preserves the previous behaviour of the unit tests: they always clear the search index after every test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This clears the search index after the test runs. My understanding of yield fixtures is that the teardown code is still run if the test fails, but there is potential that it doesn't get run if the test process were aborted for some reason. I suspect this is rare enough not to be a problem, but I'll note it as a minor hazard.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. This is preserving existing behaviour, but I agree it seems more robust to clear the search index before a test rather than after. For some reason cleaning up after a test seems to be the common and recommended approach. This seems to be a harmless change to make so I've sent a follow-up PR for it: #9653
52667ae
to
886a2bc
Compare
If we're merely not cleaning the DB as an optimization, then some tests might be OK with having "orphaned" pre-existing entries which will never be found by search. Still, this also creates potentially surprising results. I agree it would be best to find a fast way of clearing both. |
@pytest.fixture | ||
def es_client(es_client, clear_search_index): | ||
yield es_client | ||
clear_search_index() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This clears the search index after the test runs. My understanding of yield fixtures is that the teardown code is still run if the test fails, but there is potential that it doesn't get run if the test process were aborted for some reason. I suspect this is rare enough not to be a problem, but I'll note it as a minor hazard.
Clear the search index *before* each unittest rather than after, as this seems more robust. See: #9638 (comment)
Clear the search index *before* each unittest rather than after, as this seems more robust. See: #9638 (comment)
IIRC the problem is that the unittests use a DB session that's specially wrapped in a transaction that's rolled back after each test: Lines 18 to 43 in 1615569
|
b05436b
to
3c534f7
Compare
886a2bc
to
3a3bd05
Compare
Rebased |
For speed h does not normally clear the DB between functests unless the test has `@pytest.mark.parametrize("with_clean_db")`, see: #6845 At the time when this change was made the _search index_ was still being cleared before each functest which makes no sense: the search API will not return an annotation if it's not in the search index, even if the annotation is in the DB. If you aren't going to clear the DB before each functest, you shouldn't clear the search index either. A later PR accidentally broke the `always_delete_all_elasticsearch_documents` fixture so that the search index wasn't actually being cleared between functests anyway, see: #9636 This commit: 1. Removes the broken `always_delete_all_elasticsearch_documents` fixture: it doesn't do anything, and since we don't clear the DB between tests it doesn't make sense to clear the search index either. 2. Replaces the `with_clean_db` fixture with `with_clean_db_and_search_index`: it doesn't make sense to clear the DB without also clearing the search index. Longer-term I think we probably want to find a fast way to clear both the DB and search index before each functional test.
3a3bd05
to
bc4bc83
Compare
Clear the search index *before* each unittest rather than after, as this seems more robust. See: #9638 (comment)
Clear the search index *before* each unittest rather than after, as this seems more robust. See: #9638 (comment)
For speed h does not normally clear the DB between functests unless the
test has
@pytest.mark.parametrize("with_clean_db")
, see:#6845
At the time when this change was made the search index was still being
cleared before each functest which makes no sense: the search API will
not return an annotation if it's not in the search index, even if the
annotation is in the DB. If you aren't going to clear the DB before each
functest, you shouldn't clear the search index either.
A later PR accidentally broke the
always_delete_all_elasticsearch_documents
fixture so that the searchindex wasn't actually being cleared between functests anyway, see:
#9636
This commit:
always_delete_all_elasticsearch_documents
fixture: it doesn't do anything, and since we don't clear the DB
between tests it doesn't make sense to clear the search index either.
with_clean_db
fixture withwith_clean_db_and_search_index
: it doesn't make sense to clear theDB without also clearing the search index.
Longer-term I think we probably want to find a fast way to clear both
the DB and search index before each functional test.