def test_algorithm_with_invalid_output(client, algorithm_image, settings): # Override the celery settings settings.task_eager_propagates = (True, ) settings.task_always_eager = (True, ) assert Job.objects.count() == 0 # Create the algorithm image algorithm_container, sha256 = algorithm_image alg = AlgorithmImageFactory(image__from_path=algorithm_container, image_sha256=sha256, ready=True) # Make sure the job fails when trying to upload an invalid file detection_interface = ComponentInterfaceFactory( store_in_database=False, relative_path="some_text.txt", slug="detection-json-file", kind=ComponentInterface.Kind.JSON, ) alg.algorithm.outputs.add(detection_interface) alg.save() image_file = ImageFileFactory(file__from_path=Path(__file__).parent / "resources" / "input_file.tif") with capture_on_commit_callbacks(execute=True): execute_jobs(algorithm_image=alg, images=[image_file.image]) jobs = Job.objects.filter(algorithm_image=alg, inputs__image=image_file.image, status=Job.FAILURE).all() assert len(jobs) == 1 assert jobs.first().error_message == "Invalid filetype." assert len(jobs[0].outputs.all()) == 2
def test_algorithm_with_invalid_output(client, algorithm_image, settings): # Override the celery settings settings.task_eager_propagates = (True, ) settings.task_always_eager = (True, ) assert Job.objects.count() == 0 # Create the algorithm image algorithm_container, sha256 = algorithm_image alg = AlgorithmImageFactory(image__from_path=algorithm_container, image_sha256=sha256, ready=True) # Make sure the job fails when trying to upload an invalid file detection_interface = ComponentInterfaceFactory( store_in_database=False, relative_path="some_text.txt", slug="detection-json-file", kind=ComponentInterface.Kind.ANY, ) alg.algorithm.outputs.add(detection_interface) alg.save() image_file = ImageFileFactory(file__from_path=Path(__file__).parent / "resources" / "input_file.tif") civ = ComponentInterfaceValueFactory(image=image_file.image, interface=alg.algorithm.inputs.get(), file=None) with capture_on_commit_callbacks() as callbacks: create_algorithm_jobs(algorithm_image=alg, civ_sets=[{civ}]) recurse_callbacks(callbacks=callbacks) jobs = Job.objects.filter(algorithm_image=alg, inputs__image=image_file.image, status=Job.FAILURE).all() assert len(jobs) == 1 assert (jobs.first().error_message == "The file produced at /output/some_text.txt is not valid json") assert len(jobs[0].outputs.all()) == 0
def test_algorithm(client, algorithm_image, settings): # Override the celery settings settings.task_eager_propagates = (True, ) settings.task_always_eager = (True, ) assert Job.objects.count() == 0 # Create the algorithm image algorithm_container, sha256 = algorithm_image alg = AlgorithmImageFactory(image__from_path=algorithm_container, image_sha256=sha256, ready=True) # We should not be able to download image with pytest.raises(NotImplementedError): _ = alg.image.url # Run the algorithm, it will create a results.json and an output.tif image_file = ImageFileFactory(file__from_path=Path(__file__).parent / "resources" / "input_file.tif") with capture_on_commit_callbacks(execute=True): execute_jobs(algorithm_image=alg, images=[image_file.image]) jobs = Job.objects.filter(algorithm_image=alg).all() # There should be a single, successful job assert len(jobs) == 1 assert jobs[0].stdout.endswith("Greetings from stdout\n") assert jobs[0].stderr.endswith('("Hello from stderr")\n') assert jobs[0].error_message == "" assert jobs[0].status == jobs[0].SUCCESS # The job should have two ComponentInterfaceValues, # one for the results.json and one for output.tif assert len(jobs[0].outputs.all()) == 2 json_result_interface = ComponentInterface.objects.get( slug="results-json-file") json_result_civ = jobs[0].outputs.get(interface=json_result_interface) assert json_result_civ.value == { "entity": "out.tif", "metrics": { "abnormal": 0.19, "normal": 0.81 }, } heatmap_interface = ComponentInterface.objects.get(slug="generic-overlay") heatmap_civ = jobs[0].outputs.get(interface=heatmap_interface) assert heatmap_civ.image.name == "output.tif" # We add another ComponentInterface with file value and run the algorithm again detection_interface = ComponentInterfaceFactory( store_in_database=False, relative_path="detection_results.json", title="detection-json-file", slug="detection-json-file", kind=ComponentInterface.Kind.JSON, ) alg.algorithm.outputs.add(detection_interface) alg.save() image_file = ImageFileFactory(file__from_path=Path(__file__).parent / "resources" / "input_file.tif") with capture_on_commit_callbacks(execute=True): execute_jobs(algorithm_image=alg, images=[image_file.image]) jobs = Job.objects.filter(algorithm_image=alg, inputs__image=image_file.image).all() # There should be a single, successful job assert len(jobs) == 1 # The job should have three ComponentInterfaceValues, # one with the detection_results store in the file assert len(jobs[0].outputs.all()) == 3 detection_civ = jobs[0].outputs.get(interface=detection_interface) assert not detection_civ.value assert re.search("detection_results.*json$", detection_civ.file.name)