def test_workspace_deletion(app, session, default_user,
                            sample_yadage_workflow_in_db,
                            tmp_shared_volume_path, workspace, hard_delete):
    """Test workspace deletion."""
    workflow = sample_yadage_workflow_in_db
    create_workflow_workspace(sample_yadage_workflow_in_db.get_workspace())
    absolute_workflow_workspace = os.path.join(tmp_shared_volume_path,
                                               workflow.get_workspace())

    # create a job for the workflow
    workflow_job = Job(id_=uuid.uuid4(), workflow_uuid=workflow.id_)
    job_cache_entry = JobCache(job_id=workflow_job.id_)
    session.add(workflow_job)
    session.add(job_cache_entry)
    session.commit()

    # create cached workspace
    cache_dir_path = os.path.abspath(
        os.path.join(absolute_workflow_workspace, os.pardir, 'archive',
                     str(workflow_job.id_)))
    os.makedirs(cache_dir_path)

    # check that the workflow workspace exists
    assert os.path.exists(absolute_workflow_workspace)
    assert os.path.exists(cache_dir_path)
    _delete_workflow(workflow, hard_delete=hard_delete, workspace=workspace)
    if hard_delete or workspace:
        assert not os.path.exists(absolute_workflow_workspace)

    # check that all cache entries for jobs
    # of the deleted workflow are removed
    cache_entries_after_delete = JobCache.query.filter_by(
        job_id=workflow_job.id_).all()
    assert not cache_entries_after_delete
    assert not os.path.exists(cache_dir_path)
def test_start_input_parameters(app, session, default_user,
                                sample_yadage_workflow_in_db):
    """Test start workflow with inupt parameters."""
    with app.test_client() as client:
        # create workflow
        sample_yadage_workflow_in_db.status = WorkflowStatus.created
        workflow_created_uuid = sample_yadage_workflow_in_db.id_
        session.add()
        session.commit()
        workflow = Workflow.query.filter(
            Workflow.id_ == workflow_created_uuid).first()
        assert workflow.status == WorkflowStatus.created
        payload = START
        parameters = {'input_parameters': {'first': 'test'},
                      'operational_options': {}}
        # replace celery task with Mock()
        with mock.patch('reana_workflow_controller.workflow_run_manager.'
                        'current_k8s_batchv1_api_client'):
            # set workflow status to START and pass parameters
            res = client.put(url_for('api.set_workflow_status',
                             workflow_id_or_name=workflow_created_uuid),
                             query_string={"user": default_user.id_,
                                           "status": "start"},
                             content_type='application/json',
                             data=json.dumps(parameters))
            json_response = json.loads(res.data.decode())
            assert json_response.get('status') == status_dict[payload].name
            workflow = Workflow.query.filter(
                Workflow.id_ == workflow_created_uuid).first()
            assert workflow.input_parameters == parameters['input_parameters']
def test_delete_workflow(app,
                         session,
                         default_user,
                         sample_yadage_workflow_in_db,
                         status,
                         hard_delete):
    """Test deletion of a workflow in all possible statuses."""
    sample_yadage_workflow_in_db.status = status
    session.add(sample_yadage_workflow_in_db)
    session.commit()
    with app.test_client() as client:
        res = client.put(
            url_for('api.set_workflow_status',
                    workflow_id_or_name=sample_yadage_workflow_in_db.id_),
            query_string={
                'user': default_user.id_,
                'status': 'deleted'
            },
            content_type='application/json',
            data=json.dumps({'hard_delete': hard_delete}))
        if not hard_delete:
            assert sample_yadage_workflow_in_db.status == \
                WorkflowStatus.deleted
        else:
            assert session.query(Workflow).filter_by(
                id_=sample_yadage_workflow_in_db.id_).all() == []
def test_get_workflows(app, session, default_user, cwl_workflow_with_name):
    """Test listing all workflows."""
    with app.test_client() as client:
        workflow_uuid = uuid.uuid4()
        workflow_name = 'my_test_workflow'
        workflow = Workflow(
            id_=workflow_uuid,
            name=workflow_name,
            status=WorkflowStatus.finished,
            owner_id=default_user.id_,
            reana_specification=cwl_workflow_with_name['reana_specification'],
            type_=cwl_workflow_with_name[
                'reana_specification']['type'],
            logs='')
        session.add(workflow)
        session.commit()
        res = client.get(url_for('api.get_workflows'),
                         query_string={"user": default_user.id_})
        assert res.status_code == 200
        response_data = json.loads(res.get_data(as_text=True))
        expected_data = [
            {
                "id": str(workflow.id_),
                "name": workflow.name + '.1',  # Add run_number
                "status": workflow.status.name,
                "user": str(workflow.owner_id),
                "created": response_data[0]["created"],
                "size": "-"
            }
        ]

        assert response_data == expected_data
def test_workspace_deletion(app,
                            session,
                            default_user,
                            yadage_workflow_with_name,
                            tmp_shared_volume_path,
                            workspace,
                            hard_delete):
    """Test workspace deletion."""
    with app.test_client() as client:
        res = client.post(url_for('api.create_workflow'),
                          query_string={
                              "user": default_user.id_},
                          content_type='application/json',
                          data=json.dumps(yadage_workflow_with_name))
        assert res.status_code == 201
        response_data = json.loads(res.get_data(as_text=True))

        workflow = Workflow.query.filter(
            Workflow.id_ == response_data.get('workflow_id')).first()
        assert workflow

        absolute_workflow_workspace = os.path.join(
            tmp_shared_volume_path,
            workflow.get_workspace())

        # create a job for the workflow
        workflow_job = Job(id_=uuid.uuid4(), workflow_uuid=workflow.id_)
        job_cache_entry = JobCache(job_id=workflow_job.id_)
        session.add(workflow_job)
        session.add(job_cache_entry)
        session.commit()

        # check that the workflow workspace exists
        assert os.path.exists(absolute_workflow_workspace)
        with app.test_client() as client:
            res = client.put(
                url_for('api.set_workflow_status',
                        workflow_id_or_name=workflow.id_),
                query_string={
                    'user': default_user.id_,
                    'status': 'deleted'
                },
                content_type='application/json',
                data=json.dumps({'hard_delete': hard_delete,
                                 'workspace': workspace}))
        if hard_delete or workspace:
            assert not os.path.exists(absolute_workflow_workspace)

        # check that all cache entries for jobs
        # of the deleted workflow are removed
        cache_entries_after_delete = JobCache.query.filter_by(
            job_id=workflow_job.id_).all()
        assert not cache_entries_after_delete
def test_delete_workflow(app, session, default_user,
                         sample_yadage_workflow_in_db, status, hard_delete):
    """Test deletion of a workflow in all possible statuses."""
    sample_yadage_workflow_in_db.status = status
    session.add(sample_yadage_workflow_in_db)
    session.commit()

    _delete_workflow(sample_yadage_workflow_in_db, hard_delete=hard_delete)
    if not hard_delete:
        assert sample_yadage_workflow_in_db.status == WorkflowStatus.deleted
    else:
        assert session.query(Workflow).filter_by(
            id_=sample_yadage_workflow_in_db.id_).all() == []
def test_close_interactive_session_not_opened(app, session, default_user,
                                              sample_serial_workflow_in_db):
    """Test close an interactive session when session is not opened."""
    expected_data = \
        {"message": "Workflow - {} has no open interactive session."
                    .format(sample_serial_workflow_in_db.id_)}
    with app.test_client() as client:
        sample_serial_workflow_in_db.interactive_session = None
        sample_serial_workflow_in_db.interactive_session_name = None
        session.add(sample_serial_workflow_in_db)
        session.commit()
        res = client.post(
            url_for("api.close_interactive_session",
                    workflow_id_or_name=sample_serial_workflow_in_db.id_),
            query_string={"user": default_user.id_},
            content_type='application/json')
        assert res.json == expected_data
        assert res._status_code == 404
def test_close_interactive_session(app, session, default_user,
                                   sample_serial_workflow_in_db):
    """Test close an interactive session."""
    expected_data = {"message": "The interactive session has been closed"}
    sample_serial_workflow_in_db.interactive_session = \
        "/5d9b30fd-f225-4615-9107-b1373afec070"
    sample_serial_workflow_in_db.interactive_session_name = \
        "interactive-jupyter-5d9b30fd-f225-4615-9107-b1373afec070-5lswkp"
    session.add(sample_serial_workflow_in_db)
    session.commit()
    with app.test_client() as client:
        with mock.patch(
                "reana_workflow_controller.k8s.current_k8s_extensions_v1beta1") as mocks:
            res = client.post(
                url_for("api.close_interactive_session",
                        workflow_id_or_name=sample_serial_workflow_in_db.id_),
                query_string={"user": default_user.id_},
                content_type='application/json')
        assert res.json == expected_data
def test_delete_all_workflow_runs(app,
                                  session,
                                  default_user,
                                  yadage_workflow_with_name,
                                  hard_delete):
    """Test deletion of all runs of a given workflow."""
    # add 5 workflows in the database with the same name
    for i in range(5):
        workflow = Workflow(id_=uuid.uuid4(),
                            name=yadage_workflow_with_name['name'],
                            owner_id=default_user.id_,
                            reana_specification=yadage_workflow_with_name[
                                'reana_specification'],
                            operational_options={},
                            type_=yadage_workflow_with_name[
                                'reana_specification']['workflow']['type'],
                            logs='')
        session.add(workflow)
        session.commit()

    first_workflow = session.query(Workflow).\
        filter_by(name=yadage_workflow_with_name['name']).first()
    with app.test_client() as client:
        res = client.put(
            url_for('api.set_workflow_status',
                    workflow_id_or_name=first_workflow.id_),
            query_string={
                'user': default_user.id_,
                'status': 'deleted'
            },
            content_type='application/json',
            data=json.dumps({'hard_delete': hard_delete,
                             'all_runs': True}))
    if not hard_delete:
        for workflow in session.query(Workflow).\
                filter_by(name=first_workflow.name).all():
            assert workflow.status == WorkflowStatus.deleted
    else:
        assert session.query(Workflow).\
            filter_by(name=first_workflow.name).all() == []
def test_get_workflow_status_with_name(app, session, default_user,
                                       cwl_workflow_with_name):
    """Test get workflow status."""
    with app.test_client() as client:
        # create workflow
        workflow_uuid = uuid.uuid4()
        workflow_name = 'my_test_workflow'
        workflow = Workflow(
            id_=workflow_uuid,
            name=workflow_name,
            status=WorkflowStatus.finished,
            owner_id=default_user.id_,
            reana_specification=cwl_workflow_with_name['reana_specification'],
            type_=cwl_workflow_with_name[
                'reana_specification']['type'],
            logs='')
        session.add(workflow)
        session.commit()

        workflow = Workflow.query.filter(
            Workflow.name == workflow_name).first()

        res = client.get(url_for('api.get_workflow_status',
                                 workflow_id_or_name=workflow_name + '.1'),
                         query_string={"user": default_user.id_},
                         content_type='application/json',
                         data=json.dumps(cwl_workflow_with_name))
        json_response = json.loads(res.data.decode())

        assert json_response.get('status') == workflow.status.name
        workflow.status = WorkflowStatus.finished
        session.commit()

        res = client.get(url_for('api.get_workflow_status',
                                 workflow_id_or_name=workflow_name + '.1'),
                         query_string={"user": default_user.id_},
                         content_type='application/json',
                         data=json.dumps(cwl_workflow_with_name))
        json_response = json.loads(res.data.decode())
        assert json_response.get('status') == workflow.status.name
def test_stop_workflow(current_status, expected_status,
                       expected_http_status_code,
                       k8s_stop_call_count,
                       app, default_user,
                       yadage_workflow_with_name,
                       sample_serial_workflow_in_db, session):
    """Test stop workflow."""
    with app.test_client() as client:
        sample_serial_workflow_in_db.status = current_status
        session.add(sample_serial_workflow_in_db)
        session.commit()
        with mock.patch('reana_workflow_controller.workflow_run_manager.'
                        'current_k8s_batchv1_api_client') \
                as stop_workflow_mock:
            res = client.put(
                url_for('api.set_workflow_status',
                        workflow_id_or_name=sample_serial_workflow_in_db.name),
                query_string={"user": default_user.id_,
                              "status": "stop"})
            assert sample_serial_workflow_in_db.status == expected_status
            assert res.status_code == expected_http_status_code
            assert stop_workflow_mock.delete_namespaced_job.call_count \
                == k8s_stop_call_count
def test_delete_all_workflow_runs(app, session, default_user,
                                  yadage_workflow_with_name, hard_delete):
    """Test deletion of all runs of a given workflow."""
    # add 5 workflows in the database with the same name
    for i in range(5):
        workflow = Workflow(
            id_=uuid.uuid4(),
            name=yadage_workflow_with_name['name'],
            owner_id=default_user.id_,
            reana_specification=yadage_workflow_with_name[
                'reana_specification'],
            operational_options={},
            type_=yadage_workflow_with_name['reana_specification']['workflow']
            ['type'],
            logs='')
        session.add(workflow)
        if i == 4:
            workflow.status = WorkflowStatus.running
            not_deleted_one = workflow.id_
        session.commit()

    first_workflow = session.query(Workflow).\
        filter_by(name=yadage_workflow_with_name['name']).first()
    _delete_workflow(first_workflow, all_runs=True, hard_delete=hard_delete)
    if not hard_delete:
        for workflow in session.query(Workflow).\
                filter_by(name=first_workflow.name).all():
            if not_deleted_one == workflow.id_:
                assert workflow.status == WorkflowStatus.running
            else:
                assert workflow.status == WorkflowStatus.deleted
    else:
        # the one running should not be deleted
        assert len(
            session.query(Workflow).filter_by(
                name=first_workflow.name).all()) == 1