def test_method_validation(evaluation_image):
    """ The validator should set the correct sha256 and set the ready bit """
    container, sha256 = evaluation_image
    method = MethodFactory(image__from_path=container)
    # The method factory fakes the sha256 on creation
    assert method.image_sha256 != sha256
    assert method.ready == False
    validate_method_async(method_pk=method.pk)
    method = Method.objects.get(pk=method.pk)
    assert method.image_sha256 == sha256
    assert method.ready == True
def test_method_detail(client, TwoChallengeSets):
    method = MethodFactory(
        challenge=TwoChallengeSets.ChallengeSet1.challenge,
        creator=TwoChallengeSets.ChallengeSet1.admin,
    )
    validate_admin_only_view(
        viewname="evaluation:method-detail",
        two_challenge_set=TwoChallengeSets,
        reverse_kwargs={"pk": method.pk},
        client=client,
    )
def challenge_set_with_evaluation(ChallengeSet):
    """ Creates a challenge with two methods.
    To use this you must mark the test with @pytest.mark.django_db """
    EvalChallengeSet = namedtuple(
        "EvalChallengeSet", ["ChallengeSet", "method"]
    )
    ChallengeSet.challenge.use_evaluation = True
    ChallengeSet.challenge.save()
    method = MethodFactory(
        challenge=ChallengeSet.challenge, creator=ChallengeSet.creator
    )
    return EvalChallengeSet(ChallengeSet, method)
示例#4
0
def challenge_set_with_evaluation(challenge_set):
    """
    Creates a challenge with two methods.

    To use this you must mark the test with `@pytest.mark.django_db`.
    """
    eval_challenge_set = namedtuple("eval_challenge_set",
                                    ["challenge_set", "method"])
    challenge_set.challenge.use_evaluation = True
    challenge_set.challenge.save()
    method = MethodFactory(challenge=challenge_set.challenge,
                           creator=challenge_set.creator)
    return eval_challenge_set(challenge_set, method)
def test_method_validation_not_a_docker_tar(submission_file):
    """ Upload something that isnt a docker file should be invalid """
    method = MethodFactory(image__from_path=submission_file)
    assert method.ready == False

    with pytest.raises(ValidationError):
        validate_docker_image_async(pk=method.pk,
                                    app_label=method._meta.app_label,
                                    model_name=method._meta.model_name)

    method = Method.objects.get(pk=method.pk)
    assert method.ready == False
    assert 'manifest.json not found' in method.status
def test_method_validation_invalid_dockefile(alpine_images):
    """ Uploading two images in a tar archive should fail """
    method = MethodFactory(image__from_path=alpine_images)
    assert method.ready == False

    with pytest.raises(ValidationError):
        validate_docker_image_async(pk=method.pk,
                                    app_label=method._meta.app_label,
                                    model_name=method._meta.model_name)

    method = Method.objects.get(pk=method.pk)
    assert method.ready == False
    assert 'should only have 1 image' in method.status
示例#7
0
def test_method_validation_root_dockerfile(root_image):
    """Uploading two images in a tar archive should fail."""
    method = MethodFactory(image__from_path=root_image)
    assert method.ready is False

    with pytest.raises(ValidationError):
        validate_docker_image(
            pk=method.pk,
            app_label=method._meta.app_label,
            model_name=method._meta.model_name,
        )

    method = Method.objects.get(pk=method.pk)
    assert method.ready is False
    assert "runs as root" in method.status
示例#8
0
def test_submission_evaluation(
    client, evaluation_image, submission_file, settings
):
    # Override the celery settings
    settings.task_eager_propagates = (True,)
    settings.task_always_eager = (True,)
    settings.broker_url = ("memory://",)
    settings.backend = "memory"

    # Upload a submission and create a job
    dockerclient = docker.DockerClient(
        base_url=settings.CONTAINER_EXEC_DOCKER_BASE_URL
    )

    eval_container, sha256 = evaluation_image

    method = MethodFactory(
        image__from_path=eval_container, image_sha256=sha256, ready=True
    )

    # We should not be able to download methods
    response = client.get(method.image.url)
    assert response.status_code == 404

    num_containers_before = len(dockerclient.containers.list())
    num_volumes_before = len(dockerclient.volumes.list())

    # This will create a job, and we'll wait for it to be executed
    submission = SubmissionFactory(
        file__from_path=submission_file, challenge=method.challenge
    )

    # The evaluation method should clean up after itself
    assert len(dockerclient.volumes.list()) == num_volumes_before
    assert len(dockerclient.containers.list()) == num_containers_before

    # The evaluation method should return the correct answer
    assert len(submission.job_set.all()) == 1
    assert submission.job_set.all()[0].result.metrics["acc"] == 0.5

    # Try with a csv file
    submission = SubmissionFactory(
        file__from_path=Path(__file__).parent / "resources" / "submission.csv",
        challenge=method.challenge,
    )

    assert len(submission.job_set.all()) == 1
    assert submission.job_set.all()[0].result.metrics["acc"] == 0.5
示例#9
0
def test_job_detail(client, TwoChallengeSets):
    method = MethodFactory(
        challenge=TwoChallengeSets.ChallengeSet1.challenge,
        creator=TwoChallengeSets.ChallengeSet1.admin,
        ready=True,
    )
    submission = SubmissionFactory(
        challenge=TwoChallengeSets.ChallengeSet1.challenge,
        creator=TwoChallengeSets.ChallengeSet1.participant,
    )
    job = JobFactory(method=method, submission=submission)
    validate_admin_only_view(
        viewname="evaluation:job-detail",
        two_challenge_set=TwoChallengeSets,
        reverse_kwargs={"pk": job.pk},
        client=client,
    )
示例#10
0
def test_submission_evaluation(client, evaluation_image, submission_file,
                               settings):
    # Override the celery settings
    settings.task_eager_propagates = (True, )
    settings.task_always_eager = (True, )

    # Upload a submission and create an evaluation
    dockerclient = docker.DockerClient(
        base_url=settings.COMPONENTS_DOCKER_BASE_URL)

    eval_container, sha256 = evaluation_image

    method = MethodFactory(image__from_path=eval_container,
                           image_sha256=sha256,
                           ready=True)

    # We should not be able to download methods
    with pytest.raises(NotImplementedError):
        _ = method.image.url

    num_containers_before = len(dockerclient.containers.list())
    num_volumes_before = len(dockerclient.volumes.list())

    # This will create an evaluation, and we'll wait for it to be executed
    submission = SubmissionFactory(predictions_file__from_path=submission_file,
                                   challenge=method.challenge)

    # The evaluation method should clean up after itself
    assert len(dockerclient.volumes.list()) == num_volumes_before
    assert len(dockerclient.containers.list()) == num_containers_before

    # The evaluation method should return the correct answer
    assert len(submission.evaluation_set.all()) == 1
    assert (submission.evaluation_set.first().outputs.get(
        interface__slug="metrics-json-file").value["acc"] == 0.5)

    # Try with a csv file
    submission = SubmissionFactory(
        predictions_file__from_path=Path(__file__).parent / "resources" /
        "submission.csv",
        challenge=method.challenge,
    )

    assert len(submission.evaluation_set.all()) == 1
    assert (submission.evaluation_set.first().outputs.get(
        interface__slug="metrics-json-file").value["acc"] == 0.5)
示例#11
0
def test_method_validation(evaluation_image):
    """The validator should set the correct sha256 and set the ready bit."""
    container, sha256 = evaluation_image
    method = MethodFactory(image__from_path=container)

    # The method factory fakes the sha256 on creation
    assert method.image_sha256 != sha256
    assert method.ready is False

    validate_docker_image(
        pk=method.pk,
        app_label=method._meta.app_label,
        model_name=method._meta.model_name,
    )

    method = Method.objects.get(pk=method.pk)
    assert method.image_sha256 == sha256
    assert method.ready is True
def test_submission_evaluation(client, evaluation_image, submission_file):
    # Upload a submission and create a job

    dockerclient = docker.DockerClient(base_url=settings.DOCKER_BASE_URL)

    user = UserFactory()

    submission = SubmissionFactory(file__from_path=submission_file,
                                   creator=user)

    eval_container, sha256 = evaluation_image

    method = MethodFactory(image__from_path=eval_container,
                           image_sha256=sha256,
                           ready=True)

    # We should not be able to download methods
    response = client.get(method.image.url)
    assert response.status_code == 403

    job = JobFactory(submission=submission, method=method)

    num_containers_before = len(dockerclient.containers.list())
    num_volumes_before = len(dockerclient.volumes.list())

    res = evaluate_submission(job=job)

    # The evaluation method should return the correct answer
    assert res["acc"] == 0.5
    # The evaluation method should clean up after itself
    assert len(dockerclient.volumes.list()) == num_volumes_before
    assert len(dockerclient.containers.list()) == num_containers_before

    # Try with a csv file
    submission = SubmissionFactory(
        file__from_path=Path(__file__).parent / 'resources' / 'submission.csv',
        creator=user,
    )

    job = JobFactory(submission=submission, method=method)
    res = evaluate_submission(job=job)
    assert res["acc"] == 0.5