Exemplo n.º 1
0
def test_environmentbuildlist_post_with_error1(client, project, monkeypatch):
    monkeypatch.setattr(namespace_environment_builds, "make_celery",
                        raise_exception_function())

    data = client.post("/api/environment-builds/",
                       json=create_env_build_request(project.uuid,
                                                     1)).get_json()
    assert len(data["failed_requests"]) == 1
Exemplo n.º 2
0
def test_environmentbuildlist_post_revert(client, project, monkeypatch):
    monkeypatch.setattr(namespace_environment_builds, "make_celery",
                        raise_exception_function())
    client.post("/api/environment-builds/",
                json=create_env_build_request(project.uuid, 1))

    data = client.get("/api/environment-builds/").get_json()
    data = data["environment_builds"][0]
    assert data["status"] == "FAILURE"
Exemplo n.º 3
0
def test_runlist_post_revert(client, celery, pipeline, monkeypatch):
    monkeypatch.setattr(namespace_runs, "lock_environment_images_for_run",
                        raise_exception_function())

    resp = client.post(
        "/api/runs/",
        json=create_pipeline_run_spec(pipeline.project.uuid, pipeline.uuid),
    )
    assert resp.status_code == 500

    data = client.get("/api/runs/").get_json()["runs"]
    assert data[0]["status"] == "FAILURE"
Exemplo n.º 4
0
def test_environmentbuildlist_post_with_error2(client, project, monkeypatch):
    celery = CeleryMock()
    # Make it so that only the first request will go through.
    monkeypatch.setattr(
        namespace_environment_builds,
        "make_celery",
        raise_exception_function(should_trigger=lambda: bool(celery.tasks),
                                 return_value=celery),
    )

    data = client.post("/api/environment-builds/",
                       json=create_env_build_request(project.uuid,
                                                     3)).get_json()
    assert len(data["environment_builds"]) == 3
    assert len(data["failed_requests"]) == 2
Exemplo n.º 5
0
def test_job_put_revert(client, pipeline, monkeypatch):
    job_spec = create_job_spec(pipeline.project.uuid, pipeline.uuid)
    job_uuid = client.post("/api/jobs/", json=job_spec).get_json()["uuid"]

    # Cause an exception so that running the job fails.
    monkeypatch.setattr(namespace_jobs, "lock_environment_images_for_run",
                        raise_exception_function())

    resp = client.put(f"/api/jobs/{job_uuid}", json={"confirm_draft": True})
    assert resp.status_code == 500

    job = client.get(f"/api/jobs/{job_uuid}").get_json()
    assert job["status"] == "FAILURE"
    pipeline_runs = job["pipeline_runs"]
    for run in pipeline_runs:
        assert run["status"] == "FAILURE"
Exemplo n.º 6
0
def test_session_delete_revert(client, pipeline,
                               monkeypatch_interactive_session, monkeypatch):
    pipeline_spec = {
        "project_uuid": pipeline.project.uuid,
        "pipeline_uuid": pipeline.uuid,
        "pipeline_path": "pip_path",
        "project_dir": "project_dir",
        "host_userdir": "host_userdir",
    }

    client.post("/api/sessions/", json=pipeline_spec)

    monkeypatch.setattr(InteractiveSession, "from_container_IDs",
                        raise_exception_function())
    resp1 = client.delete(
        f"/api/sessions/{pipeline.project.uuid}/{pipeline.uuid}")

    resp2 = client.get(
        f"/api/sessions/{pipeline.project.uuid}/{pipeline.uuid}")

    assert resp1.status_code == 500
    assert resp2.status_code == 404
Exemplo n.º 7
0
def test_environment_build(
    image_in_local_environment,
    abort,
    build_events,
    monkeypatch,
):
    def mock_cleanup_docker_artifacts(filters):
        docker_cleanup_uuid_request.append(filters["label"][1].split("=")[1])

    def mock_put_request(self, url, json=None, *args, **kwargs):
        put_requests.append(json["status"])
        return MockRequestReponse()

    def mock_delete_request(self, url, *args, **kwargs):
        proj_uuid, env_uuid = url.split("/")[-2:]
        delete_requests.append((proj_uuid, env_uuid))
        return MockRequestReponse()

    def mock_write_environment_dockerfile(*args, **kwargs):
        pass

    def mock_prepare_build_context(task_uuid, project_uuid, environment_uuid,
                                   project_path):
        return {"snapshot_path": None, "base_image": None}

    # To keep track if requests are properly made.
    monkeypatch.setattr(requests.sessions.Session, "put", mock_put_request)
    monkeypatch.setattr(requests.sessions.Session, "delete",
                        mock_delete_request)
    # Not much use to write the dockerfile since we are monkeypatching
    # docker.
    monkeypatch.setattr(
        app.core.environment_builds,
        "write_environment_dockerfile",
        mock_write_environment_dockerfile,
    )
    # Not much use to prepare the build context since we are
    # monkeypatching docker.
    monkeypatch.setattr(app.core.environment_builds, "prepare_build_context",
                        mock_prepare_build_context)
    # Logs will be written here.
    monkeypatch.setattr(
        app.core.environment_builds,
        "__ENV_BUILD_FULL_LOGS_DIRECTORY",
        "/tmp/output_environment_build",
    )
    # To make sure the correct cleanup request is issued.
    monkeypatch.setattr(
        app.core.environment_builds,
        "cleanup_docker_artifacts",
        mock_cleanup_docker_artifacts,
    )
    # To be able to fake the cancellation of an env build.
    monkeypatch.setattr(
        app.core.environment_builds,
        "AbortableAsyncResult",
        mocked_abortable_async_result(abort),
    )
    # To mock getting an image and building an image.
    MockedDockerClient = mocked_docker_client(_NOT_TO_BE_LOGGED, build_events)

    # Patch docker get
    if not image_in_local_environment:
        monkeypatch.setattr(
            MockedDockerClient,
            "get",
            raise_exception_function(docker.errors.ImageNotFound("error")),
        )

    monkeypatch.setattr(app.core.docker_utils, "docker_client",
                        MockedDockerClient())

    socketio_data = {
        "output_logs": [],
        "has_connected": False,
        "has_disconnected": False,
    }

    # Capture build logs sent to socketio.
    monkeypatch.setattr(socketio, "Client",
                        mocked_socketio_class(socketio_data))

    put_requests = []
    delete_requests = []
    docker_cleanup_uuid_request = []

    # Inputs of the function to be tested.
    task_uuid = "task_uuid"
    # This way the name of the log file can easily be matched with the
    # actual test.
    project_uuid = "".join([
        "events:",
        str(build_events),
        "-abort:",
        str(abort),
        "-image_in_local_environment:",
        str(image_in_local_environment),
    ])
    environment_uuid = "environment_uuid"
    project_path = "project_path"

    app.core.environment_builds.build_environment_task(
        task_uuid,
        project_uuid,
        environment_uuid,
        project_path,
    )

    assert len(put_requests) == 2
    assert put_requests[0] == "STARTED"

    if abort:
        assert put_requests[1] == "ABORTED"
    elif any([event is None for event in build_events]):
        assert put_requests[1] == "FAILURE"
    else:
        assert put_requests[1] == "SUCCESS"

    assert len(delete_requests) == 1
    assert delete_requests[0] == (project_uuid, environment_uuid)

    assert len(docker_cleanup_uuid_request) == 1
    assert docker_cleanup_uuid_request[0] == task_uuid

    assert socketio_data["has_connected"]
    assert socketio_data["has_disconnected"]

    if not abort:
        if not image_in_local_environment:
            assert "Pulling image" in socketio_data["output_logs"][0]

        # We cannot rely on different messages being different elements
        # in the list, since the parent process will try to read
        # everything that is in the buffer every time, so multiple log
        # messages can be emitted togheter.
        logged_events = "".join(socketio_data["output_logs"])
        assert _NOT_TO_BE_LOGGED not in logged_events

        expected_events = []
        for event in build_events:
            if event is None:
                break
            expected_events.append(event)
        expected_events = "\n".join(expected_events)
        assert expected_events in logged_events

    # Successful tests can remove their log file.
    os.remove(
        os.path.join(
            app.core.environment_builds.__ENV_BUILD_FULL_LOGS_DIRECTORY,
            f"orchest-env-{project_uuid}-{environment_uuid}",
        ))