Skip to content

Commit 6649085

Browse files
mzegladtrawins
authored andcommitted
More functional tests for GetModelStatus (#77)
* more functional tests for getmodelstatus
1 parent 483db05 commit 6649085

9 files changed

+562
-159
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ test_local_only: venv
7070
@. $(ACTIVATE); py.test $(TEST_DIRS)/functional/test_batching.py
7171
@. $(ACTIVATE); py.test $(TEST_DIRS)/functional/test_mapping.py
7272
@. $(ACTIVATE); py.test $(TEST_DIRS)/functional/test_single_model.py
73+
@. $(ACTIVATE); py.test $(TEST_DIRS)/functional/test_update.py
7374

7475
style: venv
7576
@echo "Style-checking codebase..."

tests/functional/conftest.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,13 @@ def create_channel_for_port_single_server():
199199
return stub
200200

201201

202+
@pytest.fixture(autouse=True, scope="session")
203+
def create_channel_for_port_multi_server_status():
204+
channel = grpc.insecure_channel('localhost:9001')
205+
stub = model_service_pb2_grpc.ModelServiceStub(channel)
206+
return stub
207+
208+
202209
@pytest.fixture(autouse=True, scope="session")
203210
def create_channel_for_port_multi_server():
204211
channel = grpc.insecure_channel('localhost:9001')
@@ -234,20 +241,41 @@ def create_channel_for_batching_server_auto():
234241
return stub
235242

236243

244+
@pytest.fixture(scope="session")
245+
def create_channel_for_model_ver_pol_server_status():
246+
channel = grpc.insecure_channel('localhost:9006')
247+
stub = model_service_pb2_grpc.ModelServiceStub(channel)
248+
return stub
249+
250+
237251
@pytest.fixture(scope="session")
238252
def create_channel_for_model_ver_pol_server():
239253
channel = grpc.insecure_channel('localhost:9006')
240254
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
241255
return stub
242256

243257

258+
@pytest.fixture(scope="session")
259+
def create_channel_for_update_flow_latest_status():
260+
channel = grpc.insecure_channel('localhost:9007')
261+
stub = model_service_pb2_grpc.ModelServiceStub(channel)
262+
return stub
263+
264+
244265
@pytest.fixture(scope="session")
245266
def create_channel_for_update_flow_latest():
246267
channel = grpc.insecure_channel('localhost:9007')
247268
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
248269
return stub
249270

250271

272+
@pytest.fixture(scope="session")
273+
def create_channel_for_update_flow_specific_status():
274+
channel = grpc.insecure_channel('localhost:9008')
275+
stub = model_service_pb2_grpc.ModelServiceStub(channel)
276+
return stub
277+
278+
251279
@pytest.fixture(scope="session")
252280
def create_channel_for_update_flow_specific():
253281
channel = grpc.insecure_channel('localhost:9008')
@@ -519,7 +547,7 @@ def start_server_model_ver_policy(request, get_image, get_test_dir,
519547
return container
520548

521549

522-
@pytest.fixture(scope="class")
550+
@pytest.fixture(scope="function")
523551
def start_server_update_flow_latest(request, get_image, get_test_dir,
524552
get_docker_context):
525553
client = get_docker_context
@@ -544,7 +572,7 @@ def start_server_update_flow_latest(request, get_image, get_test_dir,
544572
return container
545573

546574

547-
@pytest.fixture(scope="class")
575+
@pytest.fixture(scope="function")
548576
def start_server_update_flow_specific(request, get_image, get_test_dir,
549577
get_docker_context):
550578
client = get_docker_context

tests/functional/test_model_version_policy.py

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,19 @@
1414
# limitations under the License.
1515
#
1616

17+
from conftest import get_model_metadata, model_metadata_response, \
18+
get_model_status, get_model_status_response_rest
19+
from tensorflow_serving.apis import get_model_metadata_pb2, \
20+
get_model_status_pb2 # noqa
21+
from ie_serving.models.models_utils import ModelVersionState, ErrorCode, \
22+
_ERROR_MESSAGE
23+
from google.protobuf.json_format import Parse
24+
1725
import sys
1826
import requests
1927
import pytest
20-
from google.protobuf.json_format import Parse
28+
2129
sys.path.append(".")
22-
from conftest import get_model_metadata, model_metadata_response # noqa
23-
from tensorflow_serving.apis import get_model_metadata_pb2 # noqa
2430

2531

2632
class TestModelVerPolicy():
@@ -94,6 +100,51 @@ def test_get_model_metadata(self, model_version_policy_models,
94100
response = stub.GetModelMetadata(request, 10)
95101
assert "Servable not found for request" in str(e.value)
96102

103+
@pytest.mark.parametrize("model_name, throw_error", [
104+
('all', [False, False, False]),
105+
('specific', [False, True, False]),
106+
('latest', [True, False, False]),
107+
])
108+
def test_get_model_status(self, model_version_policy_models,
109+
start_server_model_ver_policy,
110+
create_channel_for_model_ver_pol_server_status,
111+
model_name, throw_error):
112+
113+
print("Downloaded model files:", model_version_policy_models)
114+
115+
# Connect to grpc service
116+
stub = create_channel_for_model_ver_pol_server_status
117+
118+
versions = [1, 2, 3]
119+
for x in range(len(versions)):
120+
request = get_model_status(model_name=model_name,
121+
version=versions[x])
122+
if not throw_error[x]:
123+
response = stub.GetModelStatus(request, 10)
124+
versions_statuses = response.model_version_status
125+
version_status = versions_statuses[0]
126+
assert version_status.version == versions[x]
127+
assert version_status.state == ModelVersionState.AVAILABLE
128+
assert version_status.status.error_code == ErrorCode.OK
129+
assert version_status.status.error_message == _ERROR_MESSAGE[
130+
ModelVersionState.AVAILABLE][ErrorCode.OK]
131+
else:
132+
with pytest.raises(Exception) as e:
133+
response = stub.GetModelStatus(request, 10)
134+
assert "Servable not found for request" in str(e.value)
135+
136+
# aggregated results check
137+
if model_name == 'all':
138+
request = get_model_status(model_name=model_name)
139+
response = stub.GetModelStatus(request, 10)
140+
versions_statuses = response.model_version_status
141+
assert len(versions_statuses) == 3
142+
for version_status in versions_statuses:
143+
assert version_status.state == ModelVersionState.AVAILABLE
144+
assert version_status.status.error_code == ErrorCode.OK
145+
assert version_status.status.error_message == _ERROR_MESSAGE[
146+
ModelVersionState.AVAILABLE][ErrorCode.OK]
147+
97148
@pytest.mark.parametrize("model_name, throw_error", [
98149
('all', [False, False, False]),
99150
('specific', [False, True, False]),
@@ -162,3 +213,46 @@ def test_get_model_metadata_rest(self, model_version_policy_models,
162213
assert expected_output_metadata == output_metadata
163214
else:
164215
assert 404 == result.status_code
216+
217+
@pytest.mark.parametrize("model_name, throw_error", [
218+
('all', [False, False, False]),
219+
('specific', [False, True, False]),
220+
('latest', [True, False, False]),
221+
])
222+
def test_get_model_status_rest(self, model_version_policy_models,
223+
start_server_model_ver_policy,
224+
model_name, throw_error):
225+
226+
print("Downloaded model files:", model_version_policy_models)
227+
228+
versions = [1, 2, 3]
229+
for x in range(len(versions)):
230+
rest_url = 'http://localhost:5560/v1/models/{}/' \
231+
'versions/{}'.format(model_name, versions[x])
232+
result = requests.get(rest_url)
233+
if not throw_error[x]:
234+
output_json = result.text
235+
status_pb = get_model_status_pb2.GetModelStatusResponse()
236+
response = Parse(output_json, status_pb,
237+
ignore_unknown_fields=False)
238+
versions_statuses = response.model_version_status
239+
version_status = versions_statuses[0]
240+
assert version_status.version == versions[x]
241+
assert version_status.state == ModelVersionState.AVAILABLE
242+
assert version_status.status.error_code == ErrorCode.OK
243+
assert version_status.status.error_message == _ERROR_MESSAGE[
244+
ModelVersionState.AVAILABLE][ErrorCode.OK]
245+
else:
246+
assert 404 == result.status_code
247+
248+
# aggregated results check
249+
if model_name == 'all':
250+
rest_url = 'http://localhost:5560/v1/models/all'
251+
response = get_model_status_response_rest(rest_url)
252+
versions_statuses = response.model_version_status
253+
assert len(versions_statuses) == 3
254+
for version_status in versions_statuses:
255+
assert version_status.state == ModelVersionState.AVAILABLE
256+
assert version_status.status.error_code == ErrorCode.OK
257+
assert version_status.status.error_message == _ERROR_MESSAGE[
258+
ModelVersionState.AVAILABLE][ErrorCode.OK]

tests/functional/test_model_versions_handling.py

Lines changed: 58 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@
1414
# limitations under the License.
1515
#
1616

17+
from conftest import infer, get_model_metadata, model_metadata_response, \
18+
infer_rest, get_model_metadata_response_rest, get_model_status, \
19+
get_model_status_response_rest
20+
from ie_serving.models.models_utils import ModelVersionState, _ERROR_MESSAGE, \
21+
ErrorCode
1722
import numpy as np
1823
import sys
24+
25+
1926
sys.path.append(".")
20-
from conftest import infer, get_model_metadata, model_metadata_response,\
21-
infer_rest, get_model_metadata_response_rest # noqa
2227

2328

2429
class TestModelVersionHandling():
@@ -80,30 +85,11 @@ def test_run_inference(self, download_two_model_versions,
8085
assert output[out_name_v1].shape == (1, 1000),\
8186
'resnet model with latest version has invalid output'
8287

83-
def test_get_model_metadata(self, download_two_models,
88+
def test_get_model_metadata(self, download_two_model_versions,
8489
start_server_multi_model,
8590
create_channel_for_port_multi_server):
86-
"""
87-
<b>Description</b>
88-
Execute inference request using gRPC interface hosting multiple models
89-
90-
<b>input data</b>
91-
- directory with 2 models in IR format
92-
- docker image
93-
94-
<b>fixtures used</b>
95-
- model downloader
96-
- input data downloader
97-
- service launching
9891

99-
<b>Expected results</b>
100-
- response contains proper response about model metadata for both
101-
models set in config file:
102-
model resnet_v1_50, pnasnet_large
103-
- both served models handles appropriate input formats
104-
105-
"""
106-
print("Downloaded model files:", download_two_models)
92+
print("Downloaded model files:", download_two_model_versions)
10793

10894
# Connect to grpc service
10995
stub = create_channel_for_port_multi_server
@@ -133,6 +119,32 @@ def test_get_model_metadata(self, download_two_models,
133119
assert expected_input_metadata == input_metadata
134120
assert expected_output_metadata == output_metadata
135121

122+
def test_get_model_status(self, download_two_model_versions,
123+
start_server_multi_model,
124+
create_channel_for_port_multi_server_status):
125+
126+
print("Downloaded model files:", download_two_model_versions)
127+
128+
# Connect to grpc service
129+
stub = create_channel_for_port_multi_server_status
130+
versions = [None, 1]
131+
for x in range(len(versions)):
132+
model_name = 'resnet'
133+
request = get_model_status(model_name=model_name,
134+
version=versions[x])
135+
response = stub.GetModelStatus(request, 10)
136+
137+
versions_statuses = response.model_version_status
138+
version_status = versions_statuses[0]
139+
if x == 0:
140+
assert len(versions_statuses) == 2
141+
else:
142+
assert version_status.version == 1
143+
assert version_status.state == ModelVersionState.AVAILABLE
144+
assert version_status.status.error_code == ErrorCode.OK
145+
assert version_status.status.error_message == _ERROR_MESSAGE[
146+
ModelVersionState.AVAILABLE][ErrorCode.OK]
147+
136148
def test_run_inference_rest(self, download_two_model_versions,
137149
input_data_downloader_v1_224,
138150
start_server_multi_model):
@@ -188,30 +200,10 @@ def test_run_inference_rest(self, download_two_model_versions,
188200
assert output[out_name_v1].shape == (1, 1000), \
189201
'resnet model with latest version has invalid output'
190202

191-
def test_get_model_metadata_rest(self, download_two_models,
203+
def test_get_model_metadata_rest(self, download_two_model_versions,
192204
start_server_multi_model):
193-
"""
194-
<b>Description</b>
195-
Execute inference request using REST API interface hosting multiple
196-
models
197-
198-
<b>input data</b>
199-
- directory with 2 models in IR format
200-
- docker image
201-
202-
<b>fixtures used</b>
203-
- model downloader
204-
- input data downloader
205-
- service launching
206205

207-
<b>Expected results</b>
208-
- response contains proper response about model metadata for both
209-
models set in config file:
210-
model resnet_v1_50, pnasnet_large
211-
- both served models handles appropriate input formats
212-
213-
"""
214-
print("Downloaded model files:", download_two_models)
206+
print("Downloaded model files:", download_two_model_versions)
215207

216208
urls = ['http://localhost:5561/v1/models/resnet/metadata',
217209
'http://localhost:5561/v1/models/resnet/versions/1/metadata']
@@ -237,3 +229,24 @@ def test_get_model_metadata_rest(self, download_two_models,
237229
assert model_name == response.model_spec.name
238230
assert expected_input_metadata == input_metadata
239231
assert expected_output_metadata == output_metadata
232+
233+
def test_get_model_status_rest(self, download_two_model_versions,
234+
start_server_multi_model):
235+
236+
print("Downloaded model files:", download_two_model_versions)
237+
238+
urls = ['http://localhost:5561/v1/models/resnet',
239+
'http://localhost:5561/v1/models/resnet/versions/1']
240+
241+
for x in range(len(urls)):
242+
response = get_model_status_response_rest(urls[x])
243+
versions_statuses = response.model_version_status
244+
version_status = versions_statuses[0]
245+
if x == 0:
246+
assert len(versions_statuses) == 2
247+
else:
248+
assert version_status.version == 1
249+
assert version_status.state == ModelVersionState.AVAILABLE
250+
assert version_status.status.error_code == ErrorCode.OK
251+
assert version_status.status.error_message == _ERROR_MESSAGE[
252+
ModelVersionState.AVAILABLE][ErrorCode.OK]

0 commit comments

Comments
 (0)