-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tenant/db name verification. Fix fastapi createtenant request. Ad…
…d property test
- Loading branch information
Showing
8 changed files
with
159 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import logging | ||
from typing import Dict, Optional, Tuple | ||
import pytest | ||
from chromadb.api import AdminAPI | ||
import chromadb.api.types as types | ||
from chromadb.api.client import AdminClient, Client | ||
from chromadb.config import DEFAULT_DATABASE, DEFAULT_TENANT | ||
from chromadb.test.property.test_collections import CollectionStateMachine | ||
from hypothesis.stateful import ( | ||
Bundle, | ||
rule, | ||
initialize, | ||
multiple, | ||
run_state_machine_as_test, | ||
MultipleResults, | ||
) | ||
import chromadb.test.property.strategies as strategies | ||
|
||
|
||
class TenantDatabaseCollectionStateMachine(CollectionStateMachine): | ||
"""A collection state machine test that includes tenant and database information, | ||
and switches between them.""" | ||
|
||
tenants: Bundle[str] | ||
databases: Bundle[Tuple[str, str]] # database to tenant it belongs to | ||
tenant_to_database_to_model: Dict[ | ||
str, Dict[str, Dict[str, Optional[types.CollectionMetadata]]] | ||
] | ||
admin_client: AdminAPI | ||
curr_tenant: str | ||
curr_database: str | ||
|
||
tenants = Bundle("tenants") | ||
databases = Bundle("databases") | ||
|
||
def __init__(self, client: Client): | ||
super().__init__(client) | ||
self.api = client | ||
self.admin_client = AdminClient.from_system(client._system) | ||
|
||
@initialize() | ||
def initialize(self) -> None: | ||
self.api.reset() | ||
self.tenant_to_database_to_model = {} | ||
self.curr_tenant = DEFAULT_TENANT | ||
self.curr_database = DEFAULT_DATABASE | ||
self.api.set_tenant(DEFAULT_TENANT) | ||
self.api.set_database(DEFAULT_DATABASE) | ||
self.tenant_to_database_to_model[self.curr_tenant] = {} | ||
self.tenant_to_database_to_model[self.curr_tenant][self.curr_database] = {} | ||
|
||
@rule(target=tenants, name=strategies.tenant_database_name) | ||
def create_tenant(self, name: str) -> MultipleResults[str]: | ||
# Check if tenant already exists | ||
if name in self.tenant_to_database_to_model: | ||
with pytest.raises(Exception): | ||
self.admin_client.create_tenant(name) | ||
return multiple() | ||
|
||
self.admin_client.create_tenant(name) | ||
# When we create a tenant, create a default database for it just for testing | ||
# since the state machine could call collection operations before creating a | ||
# database | ||
self.admin_client.create_database(DEFAULT_DATABASE, tenant=name) | ||
self.tenant_to_database_to_model[name] = {} | ||
self.tenant_to_database_to_model[name][DEFAULT_DATABASE] = {} | ||
return multiple(name) | ||
|
||
@rule(target=databases, name=strategies.tenant_database_name) | ||
def create_database(self, name: str) -> MultipleResults[Tuple[str, str]]: | ||
# If database already exists in current tenant, raise an error | ||
if name in self.tenant_to_database_to_model[self.curr_tenant]: | ||
with pytest.raises(Exception): | ||
self.admin_client.create_database(name, tenant=self.curr_tenant) | ||
return multiple() | ||
|
||
self.admin_client.create_database(name, tenant=self.curr_tenant) | ||
self.tenant_to_database_to_model[self.curr_tenant][name] = {} | ||
return multiple((name, self.curr_tenant)) | ||
|
||
@rule(database=databases) | ||
def set_database_and_tenant(self, database: Dict[str, str]) -> None: | ||
# Get a database and switch to the database and the tenant it belongs to | ||
database_name = database[0] | ||
tenant_name = database[1] | ||
self.api.set_tenant(tenant_name) | ||
self.api.set_database(database_name) | ||
self.curr_database = database_name | ||
self.curr_tenant = tenant_name | ||
|
||
@rule(tenant=tenants) | ||
def set_tenant(self, tenant: str) -> None: | ||
self.api.set_tenant(tenant) | ||
self.api.set_database(DEFAULT_DATABASE) | ||
self.curr_tenant = tenant | ||
self.curr_database = DEFAULT_DATABASE | ||
|
||
@property | ||
def model(self) -> Dict[str, Optional[types.CollectionMetadata]]: | ||
return self.tenant_to_database_to_model[self.curr_tenant][self.curr_database] | ||
|
||
|
||
def test_collections(caplog: pytest.LogCaptureFixture, client: Client) -> None: | ||
caplog.set_level(logging.ERROR) | ||
run_state_machine_as_test(lambda: TenantDatabaseCollectionStateMachine(client)) # type: ignore |