Exemple #1
0
    def test_with_family_str(self):
        """ expect "Method revision name and family name" """

        family = MethodFamily(name="Example")
        method = Method(revision_name="rounded", revision_number=3, family=family)
        self.assertEqual(str(method),
                         "Example:3 (rounded)")
Exemple #2
0
def pipeline_add(request, id=None):
    """
    Creates a new Pipeline belonging to an existing PipelineFamily.
    """
    t = loader.get_template('pipeline/pipeline.html')
    method_families = MethodFamily.filter_by_user(request.user).order_by('name')

    # Retrieve this pipeline from database.
    four_oh_four = False
    try:
        family = PipelineFamily.objects.get(pk=id)
        if not family.can_be_accessed(request.user):
            four_oh_four = True
    except PipelineFamily.DoesNotExist:
        four_oh_four = True

    if four_oh_four:
        raise Http404("ID {} cannot be accessed".format(id))

    family_users_allowed = [x.pk for x in family.users_allowed.all()]
    family_groups_allowed = [x.pk for x in family.groups_allowed.all()]
    acf = metadata.forms.AccessControlForm(
        initial={
            "permissions": [family_users_allowed, family_groups_allowed]
        }
    )

    c = {
        "family": family,
        "method_families": method_families,
        "compound_datatypes": _get_compound_datatypes(request),
        "access_control_form": acf
    }

    return HttpResponse(t.render(c, request))
Exemple #3
0
def pipeline_add(request, id=None):
    """
    Creates a new Pipeline belonging to an existing PipelineFamily.
    """
    t = loader.get_template('pipeline/pipeline.html')
    method_families = MethodFamily.filter_by_user(
        request.user).order_by('name')

    # Retrieve this pipeline from database.
    four_oh_four = False
    try:
        family = PipelineFamily.objects.get(pk=id)
        if not family.can_be_accessed(request.user):
            four_oh_four = True
    except PipelineFamily.DoesNotExist:
        four_oh_four = True

    if four_oh_four:
        raise Http404("ID {} cannot be accessed".format(id))

    family_users_allowed = [x.pk for x in family.users_allowed.all()]
    family_groups_allowed = [x.pk for x in family.groups_allowed.all()]
    acf = metadata.forms.AccessControlForm(
        initial={"permissions": [family_users_allowed, family_groups_allowed]})

    c = {
        "family": family,
        "method_families": method_families,
        "compound_datatypes": _get_compound_datatypes(request),
        "access_control_form": acf
    }

    return HttpResponse(t.render(c, request))
Exemple #4
0
 def setUp(self):
     patcher = mocked_relations(Method, MethodDependency, Transformation)
     patcher.start()
     self.addCleanup(patcher.stop)
     driver = CodeResourceRevision(
         coderesource=CodeResource(filename='driver.py'))
     self.method = Method(driver=driver, family=MethodFamily())
     self.dependency = self.add_dependency('helper.py')
Exemple #5
0
    def test_no_outputs_checkOutputIndices_good(self):
        """Test output index check, one well-indexed output case."""
        driver = CodeResourceRevision(coderesource=CodeResource())

        foo = Method(driver=driver, family=MethodFamily())

        foo.check_output_indices()
        foo.clean()
Exemple #6
0
def method_add(request, pk):
    """
    Generate/validate/process forms for adding a Method to an existing MethodFamily.

    Allows for an arbitrary number of input and output forms.

    [pk] : primary key of the MethodFamily that this Method is being added to.
    """
    this_family = MethodFamily.check_accessible(pk, request.user)
    return _method_creation_helper(request, method_family=this_family)
Exemple #7
0
def method_add(request, pk):
    """
    Generate/validate/process forms for adding a Method to an existing MethodFamily.

    Allows for an arbitrary number of input and output forms.

    [pk] : primary key of the MethodFamily that this Method is being added to.
    """
    this_family = MethodFamily.check_accessible(pk, request.user)
    return _method_creation_helper(request, method_family=this_family)
Exemple #8
0
    def test_one_valid_output_checkOutputIndices_good(self):
        """Test output index check, one well-indexed output case."""

        driver = CodeResourceRevision(coderesource=CodeResource())

        foo = Method(driver=driver, family=MethodFamily())
        out = foo.outputs.create(dataset_idx=1)
        out.transformationoutput = out

        foo.check_output_indices()
        foo.clean()
Exemple #9
0
    def test_many_valid_outputs_scrambled_checkOutputIndices_good(self):
        """Test output index check, well-indexed multi-output (scrambled order) case."""

        driver = CodeResourceRevision(coderesource=CodeResource())

        foo = Method(driver=driver, family=MethodFamily())
        for i in (3, 1, 2):
            out = foo.outputs.create(dataset_idx=i)
            out.transformationoutput = out

        foo.check_output_indices()
        foo.clean()
Exemple #10
0
    def test_no_inputs_checkInputIndices_good(self):
        """
        Method with no inputs defined should have
        check_input_indices() return with no exception.
        """

        driver = CodeResourceRevision(coderesource=CodeResource())

        foo = Method(driver=driver, family=MethodFamily())

        # check_input_indices() should not raise a ValidationError
        foo.check_input_indices()
        foo.clean()
Exemple #11
0
def pipeline_new(request):
    """
    Most of the heavy lifting is done by JavaScript and HTML5.
    I don't think we need to use forms here.
    """
    t = loader.get_template('pipeline/pipeline.html')
    method_families = MethodFamily.filter_by_user(request.user).order_by('name')
    acf = metadata.forms.AccessControlForm()
    c = {
        'method_families': method_families,
        'compound_datatypes': _get_compound_datatypes(request),
        "access_control_form": acf
    }
    return HttpResponse(t.render(c, request))
Exemple #12
0
    def setUp(self):
        patcher = mocked_relations(Method, MethodFamily, Transformation)
        patcher.start()
        self.addCleanup(patcher.stop)
        self.family = MethodFamily()
        self.old_method = self.family.members.create(family=self.family,
                                                     revision_number=1,
                                                     id=101)
        self.old_method.method = self.old_method

        self.new_method = self.family.members.create(family=self.family,
                                                     revision_number=2,
                                                     id=102)
        self.new_method.method = self.new_method
Exemple #13
0
    def test_single_valid_input_checkInputIndices_good(self):
        """
        Method with a single, 1-indexed input should have
        check_input_indices() return with no exception.
        """

        driver = CodeResourceRevision(coderesource=CodeResource())

        foo = Method(driver=driver, family=MethodFamily())
        inp = foo.inputs.create(dataset_idx=1)
        inp.transformationinput = inp

        # check_input_indices() should not raise a ValidationError
        foo.check_input_indices()
        foo.clean()
Exemple #14
0
def pipeline_new(request):
    """
    Most of the heavy lifting is done by JavaScript and HTML5.
    I don't think we need to use forms here.
    """
    t = loader.get_template('pipeline/pipeline.html')
    method_families = MethodFamily.filter_by_user(
        request.user).order_by('name')
    acf = metadata.forms.AccessControlForm()
    c = {
        'method_families': method_families,
        'compound_datatypes': _get_compound_datatypes(request),
        "access_control_form": acf
    }
    return HttpResponse(t.render(c, request))
Exemple #15
0
    def test_many_ordered_valid_inputs_checkInputIndices_good(self):
        """
        Test check_input_indices on a method with several inputs,
        correctly indexed and in order.
        """

        driver = CodeResourceRevision(coderesource=CodeResource())

        foo = Method(driver=driver, family=MethodFamily())
        for i in range(3):
            inp = foo.inputs.create(dataset_idx=i + 1)
            inp.transformationinput = inp

        # check_input_indices() should not raise a ValidationError
        foo.check_input_indices()
        foo.clean()
Exemple #16
0
def pipeline_revise(request, id):
    """
    Make a new Pipeline based on the one specified by id.

    Use an AJAX transaction to load the actual Pipeline object
    from the database to front-end to render as HTML5 Canvas
    objects.
    """
    t = loader.get_template('pipeline/pipeline.html')
    method_families = MethodFamily.filter_by_user(
        request.user).order_by('name')

    # Retrieve this pipeline from database.
    four_oh_four = False
    try:
        parent_revision = Pipeline.objects.get(pk=id)
        if not parent_revision.can_be_accessed(request.user):
            four_oh_four = True
    except Pipeline.DoesNotExist:
        four_oh_four = True

    if four_oh_four:
        raise Http404("ID {} cannot be accessed".format(id))

    parent_users_allowed = [
        x.username for x in parent_revision.users_allowed.all()
    ]
    parent_groups_allowed = [
        x.name for x in parent_revision.groups_allowed.all()
    ]
    acf = metadata.forms.AccessControlForm(
        initial={"permissions": [parent_users_allowed, parent_groups_allowed]})

    parent_revision_json = json.dumps(
        PipelineSerializer(parent_revision, context={
            "request": request
        }).data)
    c = {
        "family": parent_revision.family,
        "parent_revision": parent_revision,
        "parent_revision_json": parent_revision_json,
        "method_families": method_families,
        "compound_datatypes": _get_compound_datatypes(request),
        "access_control_form": acf
    }
    return HttpResponse(t.render(c, request))
Exemple #17
0
def pipeline_revise(request, id):
    """
    Make a new Pipeline based on the one specified by id.

    Use an AJAX transaction to load the actual Pipeline object
    from the database to front-end to render as HTML5 Canvas
    objects.
    """
    t = loader.get_template('pipeline/pipeline.html')
    method_families = MethodFamily.filter_by_user(request.user).order_by('name')

    # Retrieve this pipeline from database.
    four_oh_four = False
    try:
        parent_revision = Pipeline.objects.get(pk=id)
        if not parent_revision.can_be_accessed(request.user):
            four_oh_four = True
    except Pipeline.DoesNotExist:
        four_oh_four = True

    if four_oh_four:
        raise Http404("ID {} cannot be accessed".format(id))

    parent_users_allowed = [x.username for x in parent_revision.users_allowed.all()]
    parent_groups_allowed = [x.name for x in parent_revision.groups_allowed.all()]
    acf = metadata.forms.AccessControlForm(
        initial={
            "permissions": [parent_users_allowed, parent_groups_allowed]
        }
    )

    parent_revision_json = json.dumps(
        PipelineSerializer(
            parent_revision,
            context={"request": request}
        ).data
    )
    c = {
        "family": parent_revision.family,
        "parent_revision": parent_revision,
        "parent_revision_json": parent_revision_json,
        "method_families": method_families,
        "compound_datatypes": _get_compound_datatypes(request),
        "access_control_form": acf
    }
    return HttpResponse(t.render(c, request))
Exemple #18
0
def methods(request, pk):
    """
    Display a list of all Methods within a given MethodFamily.
    """
    family = MethodFamily.check_accessible(pk, request.user)
    addable_users, addable_groups = family.other_users_groups()

    if request.method == 'POST':
        # We are attempting to update the MethodFamily's metadata/permissions.
        mf_form = MethodFamilyForm(
            request.POST,
            addable_users=addable_users,
            addable_groups=addable_groups,
            instance=family
        )

        if mf_form.is_valid():
            try:
                family.name = mf_form.cleaned_data["name"]
                family.description = mf_form.cleaned_data["description"]
                family.save()
                family.grant_from_json(mf_form.cleaned_data["permissions"])
                family.clean()

                # Success -- go back to the resources page.
                return HttpResponseRedirect('/method_families')
            except (AttributeError, ValidationError, ValueError) as e:
                LOGGER.exception(e.message)
                mf_form.add_error(None, e)

    else:
        mf_form = MethodFamilyForm(
            addable_users=addable_users,
            addable_groups=addable_groups,
            initial={"name": family.name, "description": family.description}
        )

    t = loader.get_template('method/methods.html')
    c = {
        "family": family,
        "family_form": mf_form,
        "is_admin": admin_check(request.user),
        "is_owner": request.user == family.user
    }
    return HttpResponse(t.render(c, request))
Exemple #19
0
    def setUp(self):
        super(MethodViewMockTests, self).setUp()
        patcher = mocked_relations(KiveUser,
                                   MethodFamily,
                                   Method,
                                   CodeResource,
                                   CodeResourceRevision,
                                   CompoundDatatype,
                                   ContainerFamily,
                                   Container,
                                   Transformation,
                                   TransformationInput,
                                   TransformationOutput,
                                   User,
                                   Group)
        patcher.start()
        self.addCleanup(patcher.stop)

        # noinspection PyUnresolvedReferences
        patcher = patch.object(MethodFamily._meta,
                               'default_manager',
                               MethodFamily.objects)
        patcher.start()
        self.addCleanup(patcher.stop)

        self.client = self.create_client()
        self.dev_group = Group(pk=groups.DEVELOPERS_PK)
        self.everyone = Group(pk=groups.EVERYONE_PK)
        Group.objects.add(self.dev_group, self.everyone)
        self.user = kive_user()
        self.user.groups.add(self.dev_group)
        self.other_user = User(pk=5)

        self.method_family = MethodFamily(pk='99',
                                          user=self.user)
        MethodFamily.objects.add(self.method_family)

        self.driver = CodeResourceRevision(user=self.user)
        self.driver.pk = 1337  # needed for viewing a method
        self.driver.coderesource = CodeResource()
        self.method = Method(pk='199', user=self.user)
        self.method.driver = self.driver
        self.method.family = self.method_family
        Method.objects.add(self.method)
        KiveUser.objects.add(KiveUser(pk=users.KIVE_USER_PK))
Exemple #20
0
    def test_one_invalid_output_checkOutputIndices_bad(self):
        """Test output index check, one badly-indexed output case."""

        driver = CodeResourceRevision(coderesource=CodeResource())

        foo = Method(driver=driver, family=MethodFamily())
        out = foo.outputs.create(dataset_idx=4)
        out.transformationoutput = out

        self.assertRaisesRegexp(
            ValidationError,
            "Outputs are not consecutively numbered starting from 1",
            foo.check_output_indices)

        self.assertRaisesRegexp(
            ValidationError,
            "Outputs are not consecutively numbered starting from 1",
            foo.clean)
Exemple #21
0
def methods(request, pk):
    """
    Display a list of all Methods within a given MethodFamily.
    """
    family = MethodFamily.check_accessible(pk, request.user)
    addable_users, addable_groups = family.other_users_groups()

    if request.method == 'POST':
        # We are attempting to update the MethodFamily's metadata/permissions.
        mf_form = MethodFamilyForm(request.POST,
                                   addable_users=addable_users,
                                   addable_groups=addable_groups,
                                   instance=family)

        if mf_form.is_valid():
            try:
                family.name = mf_form.cleaned_data["name"]
                family.description = mf_form.cleaned_data["description"]
                family.save()
                family.grant_from_json(mf_form.cleaned_data["permissions"])
                family.clean()

                # Success -- go back to the resources page.
                return HttpResponseRedirect('/method_families')
            except (AttributeError, ValidationError, ValueError) as e:
                LOGGER.exception(e.message)
                mf_form.add_error(None, e)

    else:
        mf_form = MethodFamilyForm(addable_users=addable_users,
                                   addable_groups=addable_groups,
                                   initial={
                                       "name": family.name,
                                       "description": family.description
                                   })

    t = loader.get_template('method/methods.html')
    c = {
        "family": family,
        "family_form": mf_form,
        "is_admin": admin_check(request.user),
        "is_owner": request.user == family.user
    }
    return HttpResponse(t.render(c, request))
Exemple #22
0
    def __init__(self, *args, **kwargs):
        super(MethodSerializer, self).__init__(*args, **kwargs)
        request = self.context.get("request")
        if request is not None:
            curr_user = request.user

            # Set the querysets of the related model fields.
            revision_parent_field = self.fields["revision_parent"]
            revision_parent_field.queryset = Method.filter_by_user(curr_user)

            family_field = self.fields["family"]
            family_field.queryset = MethodFamily.filter_by_user(curr_user)

            driver_field = self.fields["driver"]
            driver_field.queryset = CodeResourceRevision.filter_by_user(
                curr_user)

            docker_field = self.fields["docker_image"]
            docker_field.queryset = DockerImage.filter_by_user(curr_user)
Exemple #23
0
    def test_many_nonconsective_inputs_scrambled_checkInputIndices_bad(self):
        """Test input index check, badly-indexed multi-input case."""

        driver = CodeResourceRevision(coderesource=CodeResource())

        foo = Method(driver=driver, family=MethodFamily())
        for i in (2, 6, 1):
            inp = foo.inputs.create(dataset_idx=i)
            inp.transformationinput = inp

        self.assertRaisesRegexp(
            ValidationError,
            "Inputs are not consecutively numbered starting from 1",
            foo.check_input_indices)

        self.assertRaisesRegexp(
            ValidationError,
            "Inputs are not consecutively numbered starting from 1",
            foo.clean)
Exemple #24
0
    def test_one_invalid_input_checkInputIndices_bad(self):
        """
        Test input index check, one badly-indexed input case.
        """

        driver = CodeResourceRevision(coderesource=CodeResource())

        foo = Method(driver=driver, family=MethodFamily())
        inp = foo.inputs.create(dataset_idx=4)
        inp.transformationinput = inp

        # check_input_indices() should raise a ValidationError
        self.assertRaisesRegexp(
            ValidationError,
            "Inputs are not consecutively numbered starting from 1",
            foo.check_input_indices)

        self.assertRaisesRegexp(
            ValidationError,
            "Inputs are not consecutively numbered starting from 1",
            foo.clean)
Exemple #25
0
def create_method_forms(request_post, user, family=None):
    """
    Helper function for method_add() that creates Forms from the
    provided information and validates them.
    """
    query_dict = request_post.dict()
    if 'name' in query_dict:
        assert family is None
        family = MethodFamily(user=user)
        family_form = MethodFamilyForm(request_post, instance=family)
    else:
        assert family is not None
        family_form = MethodFamilyForm(
            {
                "name": family.name,
                "description": family.description
            },
            instance=family)
    family_form.is_valid()

    # Populate main form with submitted values.
    if "coderesource" in query_dict:
        method_form = MethodForm(request_post, user=user)
    else:
        method_form = MethodReviseForm(request_post)
    method_form.is_valid()
    # Determine whether the confirm_shebang button has been clicked.
    # NOTE: confirm_shebang is a checkbox html element; according to HTML spec, it will only
    # be present iff its true. ==> we cannot rely on it being present, and set the value
    # to false if it is absent.
    has_override = (request_post.get("confirm_shebang", 'off') == 'on')
    # NOTE: for shebang_val, we must differentiate between yes, no and undefined
    missing_shebang = _get_shebang_code(method_form) == SHEBANG_NO
    show_shebang_field = query_dict["SHOW_SHEBANG_FIELD"] = missing_shebang
    query_dict["SHEBANG_OK"] = (not missing_shebang or has_override)

    etxt = """The code resource should be executable, which means that the file usually starts
with a shebang: '#!'. The currently selected code resource does not.
If you know what you are doing, you can override this requirement here."""
    if show_shebang_field and not has_override:
        method_form.add_error("confirm_shebang", etxt)

    # Populate in/output forms with submitted values.
    input_forms = []
    output_forms = []
    for xput_type, formlst in [("in", input_forms), ("out", output_forms)]:
        num_forms = sum(
            k.startswith('dataset_name_{}_'.format(xput_type))
            for k in query_dict)
        for i in range(num_forms):
            auto_id = "id_%s_{}_{}".format(xput_type, i)
            t_form = TransformationXputForm(
                {
                    'dataset_name':
                    query_dict['dataset_name_{}_{}'.format(xput_type, i)]
                },
                auto_id=auto_id)
            t_form.is_valid()

            xs_form = XputStructureForm(
                {
                    'compounddatatype':
                    query_dict['compounddatatype_{}_{}'.format(xput_type, i)],
                    'min_row':
                    query_dict['min_row_{}_{}'.format(xput_type, i)],
                    'max_row':
                    query_dict['max_row_{}_{}'.format(xput_type, i)]
                },
                user=user,
                auto_id=auto_id)
            xs_form.is_valid()
            formlst.append((t_form, xs_form))

    dep_forms = _make_dep_forms(request_post.dict(), user)
    # the methods must have at least one input and output each.
    if len(input_forms) == 0:
        tx_form = TransformationXputForm(auto_id='id_%s_in_0')
        xs_form = XputStructureForm(user=user, auto_id='id_%s_in_0')
        input_forms.append((tx_form, xs_form))
    if len(output_forms) == 0:
        tx_form = TransformationXputForm(auto_id='id_%s_out_0')
        xs_form = XputStructureForm(user=user, auto_id='id_%s_out_0')
        output_forms.append((tx_form, xs_form))

    return family_form, method_form, dep_forms, input_forms, output_forms, query_dict