-
Notifications
You must be signed in to change notification settings - Fork 195
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
compatibility Test coverage #1057
base: mainline
Are you sure you want to change the base?
Conversation
…aditya/comp-test-coverage # Conflicts: # tests/compatibility_tests/compatibility_test_runner.py
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.
There are a few problematic patterns. I'll do another pass once these have been addressed:
- Unnecessary try/except (then raise) catching generic Exception class. These are superfluous
- Different test cases in for loops, meaning if one test case fails, the others don't run
- Evolution of an API post-2.0 ignored, specifically for structured index field types but possibly also others
cls.logger.debug(f"Results file deleted: {filepath}") | ||
if filepath.exists(): | ||
filepath.unlink() | ||
cls.logger.debug(f"Results file deleted: {filepath}") |
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.
I wonder if debug log level is excessive here. Do you think we will ever run this in debug mode? Is there a risk if we logged these at info level (i.e. print them all the time)?
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.
we can run it in debug mode if debugging locally. If these are logged at info level then it would make the logs too verbose and it'd be difficult to find valuable information
"indexName": structured_index_name, | ||
"type": "structured", | ||
"model": "sentence-transformers/all-MiniLM-L6-v2", | ||
"normalizeEmbeddings": False, |
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.
Non-normalized indexes need to be covered, but are unusual. If covering one, we should cover normalized
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.
fixed
}] | ||
@classmethod | ||
def tearDownClass(cls) -> None: | ||
cls.indexes_to_delete = [index['indexName'] for index in cls.indexes_to_test_on] |
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.
You could also do this in setupclass, right?
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.
I am using setupClass in prepare mode to create Marqo client and do other basic setup. I don't want to delete any indexes in prepare mode, I only want to delete an index after it has been thoroughly tested which happens after Test mode run finishes, so I've added it in tearDownClass() which will directly be called after a test run (executed by Test mode) finishes
"model": "sentence-transformers/all-MiniLM-L6-v2", | ||
"normalizeEmbeddings": False, | ||
"allFields": [ | ||
{"name": "Title", "type": "text"}, |
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.
You get the best coverage if you have all data types. That does mean you will need extra tests as some types were added in later versions. This comment applies to both index types.
try: | ||
self.logger.debug(f'Feeding documents to {self.indexes_to_test_on}') | ||
for index in self.indexes_to_test_on: | ||
if index.get("type") is not None and index.get('type') == 'structured': |
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 problem with the way this is written is if the test fails for one index type, it doesn't run for the other. You need either subtests (if you can make that work here) or separate tests.
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.
Subtests alone won't work here, because they just can be a wrapper above assertionErrors. Any other types of exceptions / errors and the subtest will fail and make the whole test fail. So I'm now using a try catch block + a subtest. Try catch block will be useful for any generic errors where as assertion errors can be logged by subtests
try: | ||
all_results[index_name][doc_id] = self.client.index(index_name).get_document(doc_id) | ||
except Exception as e: | ||
self.logger.error( |
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.
Shouldn't we fail here?
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.
No point in failing a prepare mode test. Even if we fail here - when we run test mode we will not have the context of which prepare mode tests failed.
tests/compatibility_tests/add_or_replace_documents/test_add_documents.py
Outdated
Show resolved
Hide resolved
class TestCreateStructuredIndex(BaseCompatibilityTestCase): | ||
indexes_settings_to_test_on = [ | ||
{ | ||
"type": "structured", |
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.
There are field types that 2.0 didn't support. You need to cover those
self.logger.debug(f"Printing actual_settings {actual_settings}") | ||
self.logger.debug(f"Printing expected_settings {expected_settings.get(index_name)}") | ||
except Exception as e: | ||
raise Exception(f"Exception when getting index settings for index {index_name}") from e |
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 is a bit odd. We're not expecting an error here but if one does happen the test fails. I don't think you need try/except at all
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.
try except is required so that even if one test fails the other can run. The issue here was that I was raising another exception anyway. I have changed that and now I let the other tests run before reporting exceptions
…ing structured indexes and honors API evolution
What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
feature
What is the current behavior? (You can also link to an open issue here)
Currently there are limited compatibility tests
What is the new behavior (if this is a feature change)?
more compatibility tests added as part of this PR
Does this PR introduce a breaking change? (What changes might users need to make in their application due to this PR?)
No
Have unit tests been run against this PR? (Has there also been any additional testing?)
Related Python client changes (link commit/PR here)
NA
Related documentation changes (link commit/PR here)
NA
Other information:
NA
Please check if the PR fulfills these requirements