diff --git a/model_server/conf/testing.py b/model_server/conf/testing.py index 16b656c225bcc7f1373e025c1659b8c0893a6ca7..12d93c8b884dfad672a5e7adf0f5cbe05c60eeba 100644 --- a/model_server/conf/testing.py +++ b/model_server/conf/testing.py @@ -3,10 +3,12 @@ import os import unittest from multiprocessing import Process from pathlib import Path +from shutil import copyfile import requests from urllib3 import Retry +from ..base.accessors import generate_file_accessor class TestServerBaseClass(unittest.TestCase): """ @@ -52,6 +54,22 @@ class TestServerBaseClass(unittest.TestCase): self.server_process.terminate() self.server_process.join() + def copy_input_file_to_server(self): + resp = self._get('paths') + pa = resp.json()['inbound_images'] + copyfile( + self.input_data['path'], + Path(pa) / self.input_data['name'] + ) + return self.input_data['name'] + + def get_accessor(self, accessor_id, filename=None): + resp = self._put(f'/accessors/write_to_file/{accessor_id}', query={'filename': filename}) + where_out = self._get('paths').json()['outbound_images'] + fp_out = (Path(where_out) / resp.json()) + self.assertTrue(fp_out.exists()) + return generate_file_accessor(fp_out) + def setup_test_data(): """ diff --git a/tests/base/test_api.py b/tests/base/test_api.py index b60b0e4e2afc1dba04b4f4f382867ba42981f9e0..7f692af23e42651fed96b0714a9b4798f7b5c412 100644 --- a/tests/base/test_api.py +++ b/tests/base/test_api.py @@ -11,7 +11,6 @@ from model_server.base.session import session from tests.base.test_model import DummyInstanceSegmentationModel, DummySemanticSegmentationModel czifile = conf.meta['image_files']['czifile'] -cfn = czifile['name'] """ Configure additional endpoints for testing @@ -57,19 +56,10 @@ app.include_router(router) Implement unit testing on extended base app """ + class TestServerTestCase(conf.TestServerBaseClass): app_name = 'tests.base.test_api:app' - - def copy_input_file_to_server(self): - from shutil import copyfile - - resp = self._get('paths') - pa = resp.json()['inbound_images'] - outpath = Path(pa) / cfn - copyfile( - czifile['path'], - outpath - ) + input_data = czifile class TestApiFromAutomatedClient(TestServerTestCase): @@ -126,11 +116,10 @@ class TestApiFromAutomatedClient(TestServerTestCase): ) self.assertEqual(resp.status_code, 404, resp.content.decode()) - def test_pipeline_errors_when_ids_not_found(self): - self.copy_input_file_to_server() + fname = self.copy_input_file_to_server() model_id = self._put(f'testing/models/dummy_semantic/load').json()['model_id'] - in_acc_id = self._put(f'accessors/read_from_file/{cfn}').json() + in_acc_id = self._put(f'accessors/read_from_file/{fname}').json() # respond with 409 for invalid accessor_id self.assertEqual( @@ -152,9 +141,9 @@ class TestApiFromAutomatedClient(TestServerTestCase): def test_i2i_dummy_inference_by_api(self): - self.copy_input_file_to_server() + fname = self.copy_input_file_to_server() model_id = self._put(f'testing/models/dummy_semantic/load').json()['model_id'] - in_acc_id = self._put(f'accessors/read_from_file/{cfn}').json() + in_acc_id = self._put(f'accessors/read_from_file/{fname}').json() # run segmentation pipeline on preloaded accessor resp_infer = self._put( @@ -169,14 +158,7 @@ class TestApiFromAutomatedClient(TestServerTestCase): self.assertEqual(resp_infer.status_code, 200, resp_infer.content.decode()) out_acc_id = resp_infer.json()['output_accessor_id'] self.assertTrue(self._get(f'accessors/{out_acc_id}').json()['loaded']) - - # write and re-read output - filename = 'dummy_semantic_output.tif' - self._put(f'/accessors/write_to_file/{out_acc_id}', query={'filename': filename}) - where_out = self._get('paths').json()['outbound_images'] - fp_out = (Path(where_out) / filename) - self.assertTrue(fp_out.exists()) - acc_out = generate_file_accessor(fp_out) + acc_out = self.get_accessor(out_acc_id, 'dummy_semantic_output.tif') self.assertEqual(acc_out.shape_dict['C'], 1) # validate intermediate data @@ -233,11 +215,11 @@ class TestApiFromAutomatedClient(TestServerTestCase): self.assertEqual(resp.json()[0]['message'], 'Initialized session') def test_add_and_delete_accessor(self): - self.copy_input_file_to_server() + fname = self.copy_input_file_to_server() # add accessor to session resp_add_acc = self._put( - f'accessors/read_from_file/{cfn}', + f'accessors/read_from_file/{fname}', ) acc_id = resp_add_acc.json() self.assertTrue(acc_id.startswith('auto_')) @@ -270,13 +252,5 @@ class TestApiFromAutomatedClient(TestServerTestCase): self.assertTrue(self._get(f'accessors/{acc_id}').json()['loaded']) sd = self._get(f'accessors/{acc_id}').json()['shape_dict'] self.assertEqual(self._get(f'accessors/{acc_id}').json()['filepath'], '') - - filename = 'test_output.tif' - self._put(f'/accessors/write_to_file/{acc_id}', query={'filename': filename}) - where_out = self._get('paths').json()['outbound_images'] - fp_out = (Path(where_out) / filename) - - self.assertTrue(fp_out.exists()) - - acc_out = generate_file_accessor(fp_out) + acc_out = self.get_accessor(accessor_id=acc_id, filename='test_output.tif') self.assertEqual(sd, acc_out.shape_dict) \ No newline at end of file diff --git a/tests/test_ilastik/test_ilastik.py b/tests/test_ilastik/test_ilastik.py index 8a68a2cdbf471e387dc2d237ef12cbdd1e23cfc6..b6a6f851f6cb674e29b904470a28b0b4100f3966 100644 --- a/tests/test_ilastik/test_ilastik.py +++ b/tests/test_ilastik/test_ilastik.py @@ -15,7 +15,6 @@ data = conf.meta['image_files'] output_path = conf.meta['output_path'] params = conf.meta['roiset'] czifile = conf.meta['image_files']['czifile'] -cfn = czifile['name'] ilastik_classifiers = conf.meta['ilastik_classifiers'] def _random_int(*args): @@ -200,13 +199,7 @@ class TestIlastikPixelClassification(unittest.TestCase): class TestIlastikOverApi(conf.TestServerBaseClass): - def _copy_input_file_to_server(self): - resp = self._get('paths') - pa = resp.json()['inbound_images'] - copyfile( - czifile['path'], - Path(pa) / czifile['name'] - ) + input_data = czifile def test_httpexception_if_incorrect_project_file_loaded(self): resp_load = self._put( @@ -304,9 +297,9 @@ class TestIlastikOverApi(conf.TestServerBaseClass): return model_id def test_ilastik_infer_pixel_probability(self): - self._copy_input_file_to_server() + fname = self.copy_input_file_to_server() model_id = self.test_load_ilastik_pixel_model() - in_acc_id = self._put(f'accessors/read_from_file/{cfn}').json() + in_acc_id = self._put(f'accessors/read_from_file/{fname}').json() resp_infer = self._put( f'pipelines/segment', @@ -316,11 +309,11 @@ class TestIlastikOverApi(conf.TestServerBaseClass): def test_ilastik_infer_px_then_ob(self): - self._copy_input_file_to_server() + fname = self.copy_input_file_to_server() px_model_id = self.test_load_ilastik_pixel_model() ob_model_id = self.test_load_ilastik_pxmap_to_obj_model() - in_acc_id = self._put(f'accessors/read_from_file/{cfn}').json() + in_acc_id = self._put(f'accessors/read_from_file/{fname}').json() resp_infer = self._put( 'ilastik/pipelines/pixel_then_object_classification/infer/', @@ -430,11 +423,7 @@ class TestIlastikOnMultichannelInputs(conf.TestServerBaseClass): # save output object map to file and compare obmap_id = resp_infer.json()['output_accessor_id'] - obmap_fn = self._put(f'/accessors/write_to_file/{obmap_id}').json() - where_out = self._get('paths').json()['outbound_images'] - obmap_fp = Path(where_out) / obmap_fn - self.assertTrue(obmap_fp.exists()) - obmap_acc = generate_file_accessor(obmap_fp) + obmap_acc = self.get_accessor(obmap_id) self.assertEqual(obmap_acc.shape_dict['C'], 1) # compare dimensions to input image