348 lines
11 KiB
Python
348 lines
11 KiB
Python
import pytest
|
|
|
|
from mlflow.entities.model_registry import (
|
|
ModelVersion,
|
|
ModelVersionDeploymentJobState,
|
|
ModelVersionTag,
|
|
RegisteredModel,
|
|
RegisteredModelAlias,
|
|
RegisteredModelTag,
|
|
)
|
|
from mlflow.entities.model_registry.model_version_search import ModelVersionSearch
|
|
from mlflow.entities.model_registry.registered_model_search import RegisteredModelSearch
|
|
from mlflow.protos.databricks_uc_registry_messages_pb2 import (
|
|
EncryptionDetails,
|
|
SseEncryptionAlgorithm,
|
|
SseEncryptionDetails,
|
|
TemporaryCredentials,
|
|
)
|
|
from mlflow.protos.databricks_uc_registry_messages_pb2 import ModelVersion as ProtoModelVersion
|
|
from mlflow.protos.databricks_uc_registry_messages_pb2 import (
|
|
ModelVersionStatus as ProtoModelVersionStatus,
|
|
)
|
|
from mlflow.protos.databricks_uc_registry_messages_pb2 import (
|
|
ModelVersionTag as ProtoModelVersionTag,
|
|
)
|
|
from mlflow.protos.databricks_uc_registry_messages_pb2 import (
|
|
RegisteredModel as ProtoRegisteredModel,
|
|
)
|
|
from mlflow.protos.databricks_uc_registry_messages_pb2 import (
|
|
RegisteredModelAlias as ProtoRegisteredModelAlias,
|
|
)
|
|
from mlflow.protos.databricks_uc_registry_messages_pb2 import (
|
|
RegisteredModelTag as ProtoRegisteredModelTag,
|
|
)
|
|
from mlflow.utils._unity_catalog_utils import (
|
|
_parse_aws_sse_credential,
|
|
model_version_from_uc_proto,
|
|
model_version_search_from_uc_proto,
|
|
registered_model_from_uc_proto,
|
|
registered_model_search_from_uc_proto,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"run_state",
|
|
[
|
|
"DEPLOYMENT_JOB_RUN_STATE_UNSPECIFIED",
|
|
"NO_VALID_DEPLOYMENT_JOB_FOUND",
|
|
"RUNNING",
|
|
"SUCCEEDED",
|
|
"FAILED",
|
|
"PENDING",
|
|
"APPROVAL",
|
|
],
|
|
)
|
|
def test_model_version_from_uc_proto(run_state):
|
|
from mlflow.protos.databricks_uc_registry_messages_pb2 import (
|
|
ModelVersionDeploymentJobState as ProtoModelVersionDeploymentJobState,
|
|
)
|
|
|
|
expected_model_version = ModelVersion(
|
|
name="name",
|
|
version="1",
|
|
creation_timestamp=1,
|
|
last_updated_timestamp=2,
|
|
description="description",
|
|
user_id="user_id",
|
|
source="source",
|
|
run_id="run_id",
|
|
status="READY",
|
|
status_message="status_message",
|
|
aliases=["alias1", "alias2"],
|
|
tags=[
|
|
ModelVersionTag(key="key1", value="value"),
|
|
ModelVersionTag(key="key2", value=""),
|
|
],
|
|
metrics=[],
|
|
model_id="",
|
|
params=[],
|
|
deployment_job_state=ModelVersionDeploymentJobState(
|
|
"job_123",
|
|
"run_456",
|
|
"DEPLOYMENT_JOB_CONNECTION_STATE_UNSPECIFIED",
|
|
run_state,
|
|
"task_name",
|
|
),
|
|
)
|
|
|
|
# Create protobuf with deployment job state
|
|
deployment_job_state_proto = ProtoModelVersionDeploymentJobState(
|
|
job_id="job_123",
|
|
run_id="run_456",
|
|
job_state=0, # DEPLOYMENT_JOB_CONNECTION_STATE_UNSPECIFIED
|
|
run_state=ProtoModelVersionDeploymentJobState.DeploymentJobRunState.Value(run_state),
|
|
current_task_name="task_name",
|
|
)
|
|
|
|
uc_proto = ProtoModelVersion(
|
|
name="name",
|
|
version="1",
|
|
creation_timestamp=1,
|
|
last_updated_timestamp=2,
|
|
description="description",
|
|
user_id="user_id",
|
|
source="source",
|
|
run_id="run_id",
|
|
status=ProtoModelVersionStatus.Value("READY"),
|
|
status_message="status_message",
|
|
aliases=[
|
|
ProtoRegisteredModelAlias(alias="alias1", version="1"),
|
|
ProtoRegisteredModelAlias(alias="alias2", version="2"),
|
|
],
|
|
tags=[
|
|
ProtoModelVersionTag(key="key1", value="value"),
|
|
ProtoModelVersionTag(key="key2", value=""),
|
|
],
|
|
deployment_job_state=deployment_job_state_proto,
|
|
)
|
|
actual_model_version = model_version_from_uc_proto(uc_proto)
|
|
assert actual_model_version == expected_model_version
|
|
|
|
|
|
def test_model_version_search_from_uc_proto():
|
|
expected_model_version = ModelVersionSearch(
|
|
name="name",
|
|
version="1",
|
|
creation_timestamp=1,
|
|
last_updated_timestamp=2,
|
|
description="description",
|
|
user_id="user_id",
|
|
source="source",
|
|
run_id="run_id",
|
|
status="READY",
|
|
status_message="status_message",
|
|
aliases=[],
|
|
tags=[],
|
|
deployment_job_state=ModelVersionDeploymentJobState(
|
|
"",
|
|
"",
|
|
"DEPLOYMENT_JOB_CONNECTION_STATE_UNSPECIFIED",
|
|
"DEPLOYMENT_JOB_RUN_STATE_UNSPECIFIED",
|
|
"",
|
|
),
|
|
)
|
|
uc_proto = ProtoModelVersion(
|
|
name="name",
|
|
version="1",
|
|
creation_timestamp=1,
|
|
last_updated_timestamp=2,
|
|
description="description",
|
|
user_id="user_id",
|
|
source="source",
|
|
run_id="run_id",
|
|
status=ProtoModelVersionStatus.Value("READY"),
|
|
status_message="status_message",
|
|
aliases=[
|
|
ProtoRegisteredModelAlias(alias="alias1", version="1"),
|
|
ProtoRegisteredModelAlias(alias="alias2", version="2"),
|
|
],
|
|
tags=[
|
|
ProtoModelVersionTag(key="key1", value="value"),
|
|
ProtoModelVersionTag(key="key2", value=""),
|
|
],
|
|
)
|
|
actual_model_version = model_version_search_from_uc_proto(uc_proto)
|
|
assert actual_model_version == expected_model_version
|
|
|
|
with pytest.raises(Exception): # noqa: PT011
|
|
actual_model_version.tags()
|
|
|
|
with pytest.raises(Exception): # noqa: PT011
|
|
actual_model_version.aliases()
|
|
|
|
|
|
def test_model_version_and_model_version_search_equality():
|
|
kwargs = {
|
|
"name": "name",
|
|
"version": "1",
|
|
"creation_timestamp": 1,
|
|
"last_updated_timestamp": 2,
|
|
"description": "description",
|
|
"user_id": "user_id",
|
|
"source": "source",
|
|
"run_id": "run_id",
|
|
"status": "READY",
|
|
"status_message": "status_message",
|
|
"aliases": ["alias1", "alias2"],
|
|
"tags": [
|
|
ModelVersionTag(key="key1", value="value"),
|
|
ModelVersionTag(key="key2", value=""),
|
|
],
|
|
}
|
|
model_version = ModelVersion(**kwargs)
|
|
model_version_search = ModelVersionSearch(**kwargs)
|
|
|
|
assert model_version != model_version_search
|
|
|
|
kwargs["tags"] = []
|
|
kwargs["aliases"] = []
|
|
|
|
model_version_2 = ModelVersion(**kwargs)
|
|
model_version_search_2 = ModelVersionSearch(**kwargs)
|
|
|
|
assert model_version_2 == model_version_search_2
|
|
|
|
|
|
def test_registered_model_from_uc_proto():
|
|
expected_registered_model = RegisteredModel(
|
|
name="name",
|
|
creation_timestamp=1,
|
|
last_updated_timestamp=2,
|
|
description="description",
|
|
aliases=[
|
|
RegisteredModelAlias(alias="alias1", version="1"),
|
|
RegisteredModelAlias(alias="alias2", version="2"),
|
|
],
|
|
tags=[
|
|
RegisteredModelTag(key="key1", value="value"),
|
|
RegisteredModelTag(key="key2", value=""),
|
|
],
|
|
deployment_job_id="",
|
|
deployment_job_state="DEPLOYMENT_JOB_CONNECTION_STATE_UNSPECIFIED",
|
|
)
|
|
uc_proto = ProtoRegisteredModel(
|
|
name="name",
|
|
creation_timestamp=1,
|
|
last_updated_timestamp=2,
|
|
description="description",
|
|
aliases=[
|
|
ProtoRegisteredModelAlias(alias="alias1", version="1"),
|
|
ProtoRegisteredModelAlias(alias="alias2", version="2"),
|
|
],
|
|
tags=[
|
|
ProtoRegisteredModelTag(key="key1", value="value"),
|
|
ProtoRegisteredModelTag(key="key2", value=""),
|
|
],
|
|
)
|
|
actual_registered_model = registered_model_from_uc_proto(uc_proto)
|
|
assert actual_registered_model == expected_registered_model
|
|
|
|
|
|
def test_registered_model_search_from_uc_proto():
|
|
expected_registered_model = RegisteredModelSearch(
|
|
name="name",
|
|
creation_timestamp=1,
|
|
last_updated_timestamp=2,
|
|
description="description",
|
|
aliases=[],
|
|
tags=[],
|
|
)
|
|
uc_proto = ProtoRegisteredModel(
|
|
name="name",
|
|
creation_timestamp=1,
|
|
last_updated_timestamp=2,
|
|
description="description",
|
|
aliases=[
|
|
ProtoRegisteredModelAlias(alias="alias1", version="1"),
|
|
ProtoRegisteredModelAlias(alias="alias2", version="2"),
|
|
],
|
|
tags=[
|
|
ProtoRegisteredModelTag(key="key1", value="value"),
|
|
ProtoRegisteredModelTag(key="key2", value=""),
|
|
],
|
|
)
|
|
actual_registered_model = registered_model_search_from_uc_proto(uc_proto)
|
|
assert actual_registered_model == expected_registered_model
|
|
|
|
with pytest.raises(Exception): # noqa: PT011
|
|
actual_registered_model.tags()
|
|
|
|
with pytest.raises(Exception): # noqa: PT011
|
|
actual_registered_model.aliases()
|
|
|
|
|
|
def test_registered_model_and_registered_model_search_equality():
|
|
kwargs = {
|
|
"name": "name",
|
|
"creation_timestamp": 1,
|
|
"last_updated_timestamp": 2,
|
|
"description": "description",
|
|
"aliases": [
|
|
RegisteredModelAlias(alias="alias1", version="1"),
|
|
RegisteredModelAlias(alias="alias2", version="2"),
|
|
],
|
|
"tags": [
|
|
RegisteredModelTag(key="key1", value="value"),
|
|
RegisteredModelTag(key="key2", value=""),
|
|
],
|
|
}
|
|
registered_model = RegisteredModel(**kwargs)
|
|
registered_model_search = RegisteredModelSearch(**kwargs)
|
|
|
|
assert registered_model != registered_model_search
|
|
|
|
kwargs["tags"] = []
|
|
kwargs["aliases"] = []
|
|
|
|
registered_model_2 = RegisteredModel(**kwargs)
|
|
registered_model_search_2 = RegisteredModelSearch(**kwargs)
|
|
|
|
assert registered_model_2 == registered_model_search_2
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("temp_credentials", "parsed"),
|
|
[
|
|
(TemporaryCredentials(), {}),
|
|
(
|
|
TemporaryCredentials(
|
|
encryption_details=EncryptionDetails(
|
|
sse_encryption_details=SseEncryptionDetails(
|
|
algorithm=SseEncryptionAlgorithm.SSE_ENCRYPTION_ALGORITHM_UNSPECIFIED
|
|
)
|
|
)
|
|
),
|
|
{},
|
|
),
|
|
(
|
|
TemporaryCredentials(
|
|
encryption_details=EncryptionDetails(
|
|
sse_encryption_details=SseEncryptionDetails(
|
|
algorithm=SseEncryptionAlgorithm.AWS_SSE_KMS,
|
|
aws_kms_key_arn="arn:aws:kms:us-west-2:111111111111:key/test-key-id",
|
|
)
|
|
)
|
|
),
|
|
{
|
|
"ServerSideEncryption": "aws:kms",
|
|
"SSEKMSKeyId": "arn:aws:kms:us-west-2:111111111111:key/test-key-id",
|
|
},
|
|
),
|
|
(
|
|
TemporaryCredentials(
|
|
encryption_details=EncryptionDetails(
|
|
sse_encryption_details=SseEncryptionDetails(
|
|
algorithm=SseEncryptionAlgorithm.AWS_SSE_S3,
|
|
)
|
|
)
|
|
),
|
|
{
|
|
"ServerSideEncryption": "AES256",
|
|
},
|
|
),
|
|
],
|
|
)
|
|
def test_parse_aws_sse_credential(temp_credentials, parsed):
|
|
assert _parse_aws_sse_credential(temp_credentials) == parsed
|