Skip to content

Fix timefield serialize elasticsearch #13193

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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

Talha-Rizwan
Copy link
Contributor

Issue Tracking: #13032
Extension of PR : #13080
Added tests to verify that TimeField serialization in elastic-search is now fixed.

@lb-
Copy link
Member

lb- commented Jul 2, 2025

@Talha-Rizwan thanks for picking up a PR and adding tests. Could you please look at the CI failures and work through them, including adoption of the recommendation in the comment above.

@Talha-Rizwan Talha-Rizwan requested a review from zerolab July 2, 2025 11:48
@lb-
Copy link
Member

lb- commented Jul 2, 2025

@zerolab are you able to do another review?

@zerolab
Copy link
Contributor

zerolab commented Jul 3, 2025

@lb- will have a look tomorrow

@Talha-Rizwan Talha-Rizwan requested a review from zerolab July 4, 2025 10:23
Copy link
Contributor

@zerolab zerolab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @Talha-Rizwan, a few more tweaks mostly around the new test case which I feel should be folded in TestElasticsearch7Mapping


def setUp(self):
self.author = models.Author.objects.create(name="Test Author")
self.backend = Elasticsearch7SearchBackend({})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use get_search_backend("elasticsearch")

Comment on lines +1497 to +1499
self.index.delete() # Reset the index just to be sure
self.index.put()
self.index.add_model(models.Book)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: why is this needed?

If 100% required, I'd use already established patterns, like https://github.com/wagtail/wagtail/blob/main/wagtail/search/tests/test_page_search.py#L16-L21

Comment on lines +1501 to +1516
try:
self.index.add_item(self.book)
success = True
error_message = None
except (
ElasticsearchException,
RequestError,
SerializationError,
TypeError,
) as e:
success = False
error_message = str(e)

self.assertTrue(
success, f"TimeField indexing should succeed. Error: {error_message}"
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
try:
self.index.add_item(self.book)
success = True
error_message = None
except (
ElasticsearchException,
RequestError,
SerializationError,
TypeError,
) as e:
success = False
error_message = str(e)
self.assertTrue(
success, f"TimeField indexing should succeed. Error: {error_message}"
)
self.index.add_item(self.book)

and let the test suite throw whatever exceptions it needs to

Comment on lines +1536 to +1546
try:
serializer = JSONSerializer()
serializer.dumps(document)
json_serializable = True
except (TypeError, ValueError):
json_serializable = False

self.assertTrue(
json_serializable,
"Document should be JSON serializable with Elasticsearch JSONSerializer",
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this adds any value here since other tests already check the serialisation (e.g. TestElasticsearch7Mapping.test_get_document)

@@ -1450,3 +1459,94 @@ def test_urls(self, Elasticsearch):
],
timeout=10,
)


@unittest.skipIf(ELASTICSEARCH_VERSION[0] != 7, "Elasticsearch 7 required")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few comments on specific things in the test case, but the more I look at this, the more I am convinced the tests in this test case should be folded in the other test cases, or are already covered (like the mapping or getting the results)

e.g. TestElasticsearch7Mapping.test_get_mapping should cover test_timefield_mapping and TestElasticsearch7Mapping.test_get_document (this last one would need another with a publication_date value)

@gasman
Copy link
Contributor

gasman commented Jul 4, 2025

(drive-by comment, not a full review...)

Please could you add some tests to confirm that running a search filtered by a TimeField works as expected (for example, searching for books published before 12:00), rather than only testing that indexing completes without errors? As far as I can see, an implementation that just silently discards all time values would pass the current tests, but clearly wouldn't be a valid fix.

Also, please can we make sure that we run these tests against all Elasticsearch versions, not just version 7? We don't want to ship a fix that only works on Elasticsearch 7 and breaks again when people upgrade to 8. This could be done by putting these tests in elasticsearch_common_tests.py instead - although I'm wondering if these tests really need to be Elasticsearch-specific at all. Could we not just add a test for filtering on TimeField to test_backends, alongside test_search_with_date_filter? I don't think we really need tests that go into the details of Elasticsearch mapping types - if we're able to insert TimeField data and get sensible results back out again, that's enough to demonstrate that the indexing is working correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants