def test_rename_nonexistent_name(self): pipeline = CompVizPipeline() with pytest.raises(ValueError) as e: pipeline.rename_operator('nonexistent', 'foo') assert_terms_in_exception(e, ['operator', 'name'])
def test_parameters(self): input_img = build_img((16, 16)) reference_img = build_img((36, 36)) class ReferenceImgOperator(Operator): def run(self, img: Image, ctx: PipelineContext) -> Image: return reference_img reference_operator = ReferenceImgOperator() class TestHook(PipelineHook): def before_operator(self, operator: Operator, img: Image, ctx: PipelineContext): assert img is input_img assert operator is reference_operator def after_operator(self, operator: Operator, img: Image, ctx: PipelineContext): assert img is reference_img assert operator is reference_operator def after_pipeline(self, img: Image, ctx: PipelineContext): assert img is reference_img hook = TestHook() pipeline = CompVizPipeline() pipeline.add_operator('test', reference_operator) _ = pipeline.run(input_img, hooks=[hook])
def __init__(self): super().__init__() self.cvpipeline = CompVizPipeline() self.curr_media: Optional[Image] = None self._names_generator = _OperatorNameGenerator() self.operators_changed.connect(self._on_operators_changed) self.operators_updated.connect(self._on_operators_updated)
def test_rename_keeps_operators_order(self, order_asserter_operator): pipeline = CompVizPipeline() pipeline.add_operator('op1', order_asserter_operator(0)) pipeline.add_operator('op2', order_asserter_operator(1)) pipeline.add_operator('op3', order_asserter_operator(2)) pipeline.rename_operator('op2', 'new_name') pipeline.run(build_img((16, 16)))
def create_pipeline(pipeline_config: Config, validate: Optional[bool] = True) -> CompVizPipeline: if validate: _perform_validation(pipeline_config, pipeline_schema) pipeline = CompVizPipeline() for op_config in pipeline_config['pipeline']: operator = create_operator(op_config['config'], validate=False) pipeline.add_operator(op_config['name'], operator) return pipeline
def test_happy_path(self, idx): op_to_move_name = 'op1' op_to_move = TestOperator() target = 2 pipeline = CompVizPipeline() pipeline.add_operator('op0', TestOperator()) pipeline.add_operator(op_to_move_name, op_to_move) pipeline.add_operator('op2', TestOperator()) pipeline.move_operator(idx, target) assert list(pipeline.operators.values())[target] == op_to_move assert list(pipeline.operators.keys())[target] == op_to_move_name
def test_pipeline_execution_order(order_asserter_operator): pipeline = CompVizPipeline() pipeline.add_operator('op1', order_asserter_operator(0)) pipeline.add_operator('op2', order_asserter_operator(1)) pipeline.add_operator('op3', order_asserter_operator(2)) pipeline.run(build_img((16, 16)))
def test_happy_path(self, idx): operator_to_delete = 'op_to_delete' operator_to_stay = 'op_to_stay' pipeline = CompVizPipeline() pipeline.add_operator(operator_to_stay, TestOperator()) pipeline.add_operator(operator_to_delete, TestOperator()) pipeline.remove_operator(idx) assert list(pipeline.operators.keys()) == [operator_to_stay]
def load_config(self, fname: str): with open(fname, 'r') as fin: try: self.cvpipeline = CompVizPipeline.load(fin) self.operators_changed.emit() except ConfigParsingError as e: self.loading_failed.emit(e)
def test_rename_keeps_order(self): pipeline = CompVizPipeline() pipeline.add_operator('op1', TestOperator()) pipeline.add_operator('op2', TestOperator()) pipeline.add_operator('op3', TestOperator()) pipeline.rename_operator('op2', 'renamed') assert list(pipeline.operators.keys()) == ['op1', 'renamed', 'op3']
def test_add_info_works(self): info_name = 'info_name' info_value = object() class TestCtxAddInfo(Operator): def run(self, img: Image, ctx: PipelineContext) -> Image: ctx.add_info(info_name, info_value) return img pipeline = CompVizPipeline() op_name1 = 'test_op1' pipeline.add_operator(op_name1, TestCtxAddInfo()) op_name2 = 'test_op2' pipeline.add_operator(op_name2, TestCtxAddInfo()) _, returned_ctx = pipeline.run(build_img((16, 16))) expected_info = { op_name1: { info_name: info_value }, op_name2: { info_name: info_value } } actual_info = returned_ctx.info assert actual_info == expected_info
def test_rename_keeps_saving_order(self): pipeline = CompVizPipeline() pipeline.add_operator('op1', TestOperator()) pipeline.add_operator('op2', TestOperator()) pipeline.add_operator('op3', TestOperator()) pipeline.rename_operator('op2', 'renamed') stream = StringIO() pipeline.save(stream) stream.seek(0) config = yaml.safe_load(stream) operators_order = [ op_config['name'] for op_config in config['pipeline'] ] assert operators_order == ['op1', 'renamed', 'op3']
def test_operators_params(self, config_stream): pipeline = CompVizPipeline.load(config_stream) ops = pipeline.operators op1 = ops['op1'] op2 = ops['op2'] assert op1.param1 == OP1_PARAM1 assert op1.param2 == OP1_PARAM2 assert op2.param1 == OP2_PARAM1 assert op2.param2 == OP2_PARAM2
def test_duplicated_name(self): pipeline = CompVizPipeline() pipeline.add_operator('test_op', TestOperator()) with pytest.raises(ValueError) as e: pipeline.add_operator('test_op', TestOperator()) assert_terms_in_exception(e, ['duplicated'])
def test_operators_property_order(): pipeline = CompVizPipeline() pipeline.add_operator('op1', TestOperator()) pipeline.add_operator('op2', TestOperator()) pipeline.add_operator('op3', TestOperator()) assert list(pipeline.operators.keys()) == ['op1', 'op2', 'op3']
def test_invalid_target(self, target): pipeline = CompVizPipeline() pipeline.add_operator('op0', TestOperator()) pipeline.add_operator('op1', TestOperator()) with pytest.raises(ValueError) as e: pipeline.move_operator('op0', target) assert_terms_in_exception(e, ['invalid', 'target'])
def test_invalid_index(self, idx): pipeline = CompVizPipeline() pipeline.add_operator('op0', TestOperator()) pipeline.add_operator('op1', TestOperator()) with pytest.raises(ValueError) as e: pipeline.get_operator_name(idx) assert_terms_in_exception(e, ['invalid', 'index'])
def test_rename_operator(self): pipeline = CompVizPipeline() starting_name = 'some_name' new_name = 'another_name' op = TestOperator() pipeline.add_operator(starting_name, op) pipeline.add_operator('foo', TestOperator()) pipeline.add_operator('bar', TestOperator()) expected_len = len(pipeline.operators) pipeline.rename_operator(starting_name, new_name) assert len(pipeline.operators) == expected_len assert new_name in pipeline.operators assert pipeline.operators[new_name] is op
def test_set_ctx_original_img(self, img): class TestCtxOriginalImgOperator(Operator): def run(self, img_: Image, ctx: PipelineContext) -> Image: assert np.all(ctx.original_img == img_) return img_ pipeline = CompVizPipeline() pipeline.add_operator('test_op', TestCtxOriginalImgOperator()) pipeline.run(img)
def test_rename_to_existent_name(self): pipeline = CompVizPipeline() pipeline.add_operator('op1', TestOperator()) pipeline.add_operator('op2', TestOperator()) with pytest.raises(ValueError) as e: pipeline.rename_operator('op1', 'op2') assert_terms_in_exception(e, ['name'])
def test_operator_fail(): class FailingOperator(Operator): def run(self, img: Image, ctx: PipelineContext) -> Image: raise ValueError('Failed') pipeline = CompVizPipeline() pipeline.add_operator('op', FailingOperator()) with pytest.raises(OperatorFailedError): pipeline.run(build_img((16, 16)))
def test_check_op_return(self, return_value): class TestWrongReturnOperator(Operator): def run(self, img: np.ndarray, ctx: PipelineContext) -> Any: return return_value pipeline = CompVizPipeline() pipeline.add_operator('test_op', TestWrongReturnOperator()) with pytest.raises(BadImageError) as e: pipeline.run(build_img((16, 16))) assert_terms_in_exception(e, ['return', 'invalid'])
def test_gray_only_flag(self): @settings.GRAY_ONLY(True) class TestOnlyGrayFlagOperator(Operator): def run(self, img: Image, ctx: PipelineContext) -> Image: return img pipeline = CompVizPipeline() pipeline.add_operator('test_op', TestOnlyGrayFlagOperator()) with pytest.raises(OperatorFailedError) as e: pipeline.run(build_img((16, 16), rgb=True)) assert_terms_in_exception(e, ["expect", "gray"])
def test_operator_cant_alter_original_img(self): class TestCtxOriginalImg(Operator): def run(self, img: Image, ctx: PipelineContext) -> Image: original_img = ctx.original_img original_img[10, ...] = 255 return img pipeline = CompVizPipeline() pipeline.add_operator('test_op', TestCtxOriginalImg()) test_img = build_img((128, 128), kind='black') with pytest.raises(OperatorFailedError) as e: pipeline.run(test_img) assert_terms_in_exception(e, ['read-only'])
class EzCVController(QObject): show_media = pyqtSignal(Image) operators_changed = pyqtSignal() operators_updated = pyqtSignal() operator_failed = pyqtSignal(OperatorFailedError) loading_failed = pyqtSignal(ConfigParsingError) def __init__(self): super().__init__() self.cvpipeline = CompVizPipeline() self.curr_media: Optional[Image] = None self._names_generator = _OperatorNameGenerator() self.operators_changed.connect(self._on_operators_changed) self.operators_updated.connect(self._on_operators_updated) def add_operator(self, operator_cls: Type[Operator]): operator = operator_cls() operator_name = self._names_generator.generate_name(operator_cls) self.cvpipeline.add_operator(operator_name, operator) self.operators_changed.emit() def process_curr_media(self): if self.curr_media is not None: try: result_img, ctx = self.cvpipeline.run(self.curr_media) self.show_media.emit(result_img) except OperatorFailedError as e: self.operator_failed.emit(e) self.show_media.emit(self.curr_media) def update_operator(self, name: str, param_name: str, param_value: Any): setattr(self.operators[name], param_name, param_value) self.operators_updated.emit() def load_media(self, fname: str): img = cv2.imread(fname) if img is None: raise ValueError("Couldn't open image located at %s" % fname) self.curr_media = img self.process_curr_media() def load_config(self, fname: str): with open(fname, 'r') as fin: try: self.cvpipeline = CompVizPipeline.load(fin) self.operators_changed.emit() except ConfigParsingError as e: self.loading_failed.emit(e) @property def operators(self): return self.cvpipeline.operators def _on_operators_changed(self): self.process_curr_media() def _on_operators_updated(self): self.process_curr_media()
def test_operators_types(self, config_stream): pipeline = CompVizPipeline.load(config_stream) assert all( isinstance(op, TestOperator) for op in pipeline.operators.values())
def test_operators_names(self, config_stream): pipeline = CompVizPipeline.load(config_stream) assert list(pipeline.operators.keys()) == ["op1", "op2"]
def test_return_type(self, config_stream): pipeline = CompVizPipeline.load(config_stream) assert isinstance(pipeline, CompVizPipeline)
def test_pipeline_save_writes(self): pipeline = CompVizPipeline() output_stream = Mock() output_stream.write = Mock() pipeline.save(output_stream) output_stream.write.assert_called()
def test_pipeline_save_runs(self): pipeline = CompVizPipeline() pipeline.save(StringIO())