Skip to content

Commit 19ec921

Browse files
committed
Added unit tests.
1 parent d0309f4 commit 19ec921

File tree

2 files changed

+130
-4
lines changed

2 files changed

+130
-4
lines changed

ads/model/datascience_model.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,8 +1508,7 @@ def add_artifact(
15081508
self.set_spec(self.CONST_MODEL_FILE_DESCRIPTION, self.empty_json)
15091509

15101510
# Get object storage client
1511-
authData = default_signer()
1512-
self.object_storage_client = oc.OCIClientFactory(**authData).object_storage
1511+
self.object_storage_client = oc.OCIClientFactory(**(self.dsc_model.auth)).object_storage
15131512

15141513
# Remove if the model already exists
15151514
self.remove_artifact(uri=uri)
@@ -1631,7 +1630,7 @@ def findModelIdx():
16311630

16321631
def _extract_oci_uri_components(self, uri: str):
16331632
# Define the regular expression pattern to match the URI format
1634-
pattern = r"oci://(?P<bucket_name>[^@]+)@(?P<namespace>[^/]+)(?:/(?P<prefix>.*))?"
1633+
pattern = r"oci://(?P<bucket_name>[^@]+)@(?P<namespace>[^/]+)(?:/(?P<prefix>.*))?" # todo: remove regex
16351634

16361635
# Use re.match to apply the pattern to the URI
16371636
match = re.match(pattern, uri)

tests/unitary/default_setup/model/test_datascience_model.py

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@
4040
OCIDataScienceModel,
4141
)
4242
from oci.data_science.models import ModelProvenance
43+
from oci.object_storage.models.object_version_summary import ObjectVersionSummary
4344
from ads.config import AQUA_SERVICE_MODELS_BUCKET as SERVICE_MODELS_BUCKET
4445

45-
4646
MODEL_OCID = "ocid1.datasciencemodel.oc1.iad.<unique_ocid>"
4747

4848
OCI_MODEL_PAYLOAD = {
@@ -163,6 +163,66 @@
163163
"Content-Length": _MAX_ARTIFACT_SIZE_IN_BYTES + 100,
164164
}
165165

166+
MODEL_BY_REF_JSON = {
167+
"version": "1.0",
168+
"type": "modelOSSReferenceDescription",
169+
"models": [
170+
{
171+
"namespace": "ociodscdev",
172+
"bucketName": "unzip-multi-model",
173+
"prefix": "model-linear-1",
174+
"objects": [
175+
{
176+
"name": "model-linear-1/linear-1.pkl",
177+
"version": "ee260f4a-920a-4b4e-974a-c13a1032558e",
178+
"sizeInBytes": 565
179+
}
180+
]
181+
},
182+
{
183+
"namespace": "ociodscdev",
184+
"bucketName": "unzip-multi-model",
185+
"prefix": "model-linear-2",
186+
"objects": [
187+
{
188+
"name": "model-linear-2/linear-2.pkl",
189+
"version": "dc26a7d2-8041-4b37-8ed0-9e8c10869340",
190+
"sizeInBytes": 565
191+
}
192+
]
193+
},
194+
{
195+
"namespace": "ociodscdev",
196+
"bucketName": "unzip-multi-model",
197+
"prefix": "model-linear-3",
198+
"objects": [
199+
{
200+
"name": "model-linear-3/linear-3.pkl",
201+
"version": "a22c1211-f7d4-4fd4-96d8-4e3a048c5cf7",
202+
"sizeInBytes": 565
203+
}
204+
]
205+
},
206+
{
207+
"namespace": "ociodscdev",
208+
"bucketName": "unzip-multi-model",
209+
"prefix": "",
210+
"objects": [
211+
{
212+
"name": "runtime.yaml",
213+
"version": "30afb1a6-ab1f-42a3-95e3-09f61a0046fd",
214+
"sizeInBytes": 334
215+
},
216+
{
217+
"name": "score.py",
218+
"version": "c4ccaf96-05be-4174-ac3b-15dce2f558fe",
219+
"sizeInBytes": 772
220+
}
221+
]
222+
}
223+
]
224+
}
225+
CONST_MODEL_FILE_DESCRIPTION = "modelDescription"
166226

167227
class TestDataScienceModel:
168228
DEFAULT_PROPERTIES_PAYLOAD = {
@@ -1070,3 +1130,70 @@ def test_download_artifact_for_model_created_by_reference(
10701130
)
10711131

10721132
mock_large_download.assert_called()
1133+
1134+
1135+
1136+
@patch("ads.common.oci_client.OCIClientFactory")
1137+
def test_add_artifact(self, mock_oci_client_factory):
1138+
r = ObjectVersionSummary()
1139+
r.name = "model-linear-2/linear-2.pkl"
1140+
r.size = 566
1141+
r.time_modified = "2024-04-22T12:34:26.670000+00:00"
1142+
r.version_id = "dc26a7d2-8041-4b37-8ed0-9e8c10869340"
1143+
resp = [r]
1144+
1145+
# Mock response object
1146+
mock_response = MagicMock()
1147+
mock_response.data.items = resp
1148+
mock_response.has_next_page = False
1149+
mock_response.next_page = None
1150+
1151+
# Mock object storage client
1152+
mock_object_storage_client = MagicMock()
1153+
mock_object_storage_client.list_object_versions.return_value = mock_response
1154+
1155+
mock_oci_client_factory.return_value.object_storage = mock_object_storage_client
1156+
1157+
# self.mock_dsc_model
1158+
self.mock_dsc_model.add_artifact(uri="oci://bucket@namespace/prefix")
1159+
expected_out = {
1160+
'version': '1.0',
1161+
'type': 'modelOSSReferenceDescription',
1162+
'models': [
1163+
{
1164+
'namespace': 'namespace',
1165+
'bucketName': 'bucket',
1166+
'prefix': 'prefix',
1167+
'objects': [
1168+
{
1169+
'name': 'model-linear-2/linear-2.pkl',
1170+
'version': 'dc26a7d2-8041-4b37-8ed0-9e8c10869340',
1171+
'sizeInBytes': 566
1172+
}
1173+
]
1174+
}
1175+
]
1176+
}
1177+
assert self.mock_dsc_model.model_file_description == expected_out
1178+
self.mock_dsc_model.remove_artifact(uri="oci://bucket@namespace/prefix")
1179+
assert self.mock_dsc_model.model_file_description != expected_out
1180+
expected_out = {
1181+
'version': '1.0',
1182+
'type': 'modelOSSReferenceDescription',
1183+
'models': []
1184+
}
1185+
assert self.mock_dsc_model.model_file_description == expected_out
1186+
1187+
def test_remove_artifact(self):
1188+
self.mock_dsc_model.remove_artifact(uri="oci://unzip-multi-model@ociodscdev/model-linear-1")
1189+
assert self.mock_dsc_model.model_file_description == None
1190+
1191+
self.mock_dsc_model.set_spec(CONST_MODEL_FILE_DESCRIPTION, deepcopy(MODEL_BY_REF_JSON))
1192+
assert self.mock_dsc_model.model_file_description == MODEL_BY_REF_JSON
1193+
1194+
self.mock_dsc_model.remove_artifact(uri="oci://unzip-multi-model@ociodscdev/model-linear-1")
1195+
assert self.mock_dsc_model.model_file_description != MODEL_BY_REF_JSON
1196+
1197+
exptected_json = deepcopy(MODEL_BY_REF_JSON)
1198+
exptected_json["models"] = exptected_json["models"][1:]
1199+
assert self.mock_dsc_model.model_file_description == exptected_json

0 commit comments

Comments
 (0)