Exemple #1
0
    def __init__(self, plan_id=None, project_id=None, uri=None,
                 suds_object=None):
        """Plan Constructor

        Args:
            plan_id: ID of the plan
            project_id: ID of the project that contains the specific plan
                        required when plan_id is given
            uri: the SubterraURI of the plan to load
            suds_object: the Polarion Plan object

        Returns:
            None

        References:
            Planning.getPlanById
            Planning.getPlanByUri
        """
        super(self.__class__, self).__init__(obj_id=plan_id,
                                             suds_object=suds_object)
        if plan_id:
            if not project_id:
                raise PyleroLibException("When plan_id is passed in, "
                                           "project_id is required")
            self._suds_object = self.session.planning_client.service. \
                getPlanById(project_id, plan_id)
        elif uri:
            self._suds_object = self.session.planning_client.service. \
                getPlanByUri(uri)
        if plan_id or uri:
            if getattr(self._suds_object, "_unresolvable", True):
                raise PyleroLibException(
                    "The Plan {0} was not found.".format(plan_id))
Exemple #2
0
    def check_valid_field_values(self, val, enum_id, additional_parms,
                                 control=None):
        """verifies id the value passed in is valid for the enum or object
        passed in. for example, if we want to see if a valid user is given,
        this will try to instantiate the User class with the given parameter
        and additional parms. If it fails, it is not a valid value.

        Args:
            val: the value you want to set it to.
            enum_id: the enumeration or object to validate against
            additional_parms (dict): parms needed to instantiate class passed
                                    in as enum_id
            control: the control key for the enumeration. default:None
        """
        if isinstance(enum_id, type):
            try:
                # try to instantiate the object with the value and additional
                # parms. If that works, it is a valid value
                enum_id(val, **additional_parms)
            except Exception:
                raise PyleroLibException(
                    "{0} is not a valid value for {1}"
                    .format(val, enum_id.__name__))
        else:
            valid_values = self.get_valid_field_values(enum_id, control)
            if val not in valid_values:
                raise PyleroLibException("Acceptable values for {0} are:"
                                           "{1}".format(enum_id, valid_values))
Exemple #3
0
    def __init__(self):
        defaults = {"cachingpolicy": "0",
                    "timeout": "120"}


        config = SafeConfigParser(defaults)
        # Check for existence of config file and config_section
        if not config.read([self.GLOBAL_CONFIG, self.LOCAL_CONFIG,
                            self.CURDIR_CONFIG]) or \
                not config.has_section(self.CONFIG_SECTION):
            # Check for mandatory environ variables if config file is not found
            if not all(os.environ.get(item) for item in ('POLARION_URL',
                'POLARION_REPO', 'POLARION_USERNAME', 'POLARION_PASSWORD',
                'POLARION_PROJECT')):
                raise PyleroLibException("The config files/ENV vars do not "
                                        "exist or are not of the correct "
                                        "format. Valid files are: {0}, {1} "
                                        "or {2}" .format(self.GLOBAL_CONFIG,
                                                self.LOCAL_CONFIG,
                                                self.CURDIR_CONFIG))
        self.server_url = os.environ.get("POLARION_URL") or \
                     config.get(self.CONFIG_SECTION, "url")
        self.repo = os.environ.get("POLARION_REPO") or \
               config.get(self.CONFIG_SECTION, "svn_repo")
        self.login = os.environ.get("POLARION_USERNAME") or \
                config.get(self.CONFIG_SECTION, "user")
        self.pwd = os.environ.get("POLARION_PASSWORD") or \
              config.get(self.CONFIG_SECTION, "password")

        try:
            self.timeout = os.environ.get("POLARION_TIMEOUT") or \
                    config.get(self.CONFIG_SECTION, "timeout")
        except:
            self.timeout = config.defaults['timeout']

        try:
            self.timeout = int(self.timeout)
        except ValueError:
            raise PyleroLibException("The timeout value in the config"
                                       " file must be an integer")
        self.proj = os.environ.get("POLARION_PROJECT") or \
               config.get(self.CONFIG_SECTION, "default_project")
        try:
            self.cert_path = os.environ.get("POLARION_CERT_PATH") or \
                        config.get(self.CONFIG_SECTION, "cert_path")
        except:
            self.cert_path = None

        if not (self.server_url and self.login and self.proj):
            raise PyleroLibException("The config files must contain "
                                       "valid values for: url, user, "
                                       "password and default_project")
Exemple #4
0
    def __init__(self, user_id=None, suds_object=None, uri=None):
        """User constructor.

        Args:
            user_id: when given, the object is populated with user's data
            suds_object: Polarion User object. When given, the object is
                          populated by object data.
            uri: when given, the object is populated with user's data

        Notes:
            Either user_id, suds_object or uri can be passed in, not multiple

        References:
            Project.getUser
            Project.getUserByUri
        """
        super(self.__class__, self).__init__(user_id, suds_object)
        # user_id will be null if called from the get_users class function
        if user_id or uri:
            if user_id:
                self._suds_object = \
                    self.session.project_client.service.getUser(user_id)
            elif uri:
                self._suds_object = self.session.project_client.service. \
                    getUserByUri(uri)
            if getattr(self._suds_object, "_unresolvable", True):
                raise PyleroLibException(
                    "The user {0} was not found.".format(user_id))
Exemple #5
0
 def _verify_obj(self):
     # verifies if the object contains a suds object from the server by
     # checking if the uri field is populated. If no URI it didn't come from
     # the server
     if not getattr(self, "uri", None):
         raise PyleroLibException("There is no {0} loaded".format(
             self.__class__.__name__))
Exemple #6
0
    def __init__(self,
                 project_id=None,
                 doc_with_space=None,
                 fields=None,
                 uri=None,
                 suds_object=None):
        """constructor for the Module object. Gets the module object from the
        Polarion server based on parameters passed in.

        Args:
            project_id: the project where the module is located
            doc_with_space: specific space/doc_name of the repository,
                            required if project_id is given
                            (Testing, Development, ...)
            fields: optional list of fields that should be contained in the
                     returned object.
            uri: The Polarion specific uri of the module object
            suds_object: the WSDL Module object

        Returns:
            None

        References:
            Tracker.getModuleByLocation
            Tracker.getModuleByLocationWithFields
            Tracker.getModuleByUri
            Tracker.getModuleByUriWithFields
        """
        super(self.__class__, self).__init__(suds_object=suds_object)
        # function names and parameter lists generated dynamically based on
        # parameters passed in.
        if doc_with_space or uri:
            function_name = "getModuleBy"
            parms = []
            if doc_with_space:
                function_name += "Location"
                parms += [project_id, doc_with_space]
            elif uri:
                function_name += "Uri"
                parms.append(uri)
            if fields:
                function_name = "WithFields"
                parms.append(self._convert_obj_fields_to_polarion(fields))
            self._suds_object = getattr(self.session.tracker_client.service,
                                        function_name)(*parms)
            if getattr(self._suds_object, "_unresolvable", True):
                raise PyleroLibException(
                    "The Document {0} was not found.".format(doc_with_space
                                                             or uri))
Exemple #7
0
    def _arr_obj_setter(self, val, field_name):
        """set function for attributes that reference an array of objects. It
        requires a single instance or list of either Pylero or WSDL objects
        or an empty list.
        An empty list erases the attribute value.
        Otherwise it sets the attribute the value passed in.

        Args:
            val: the value that the property is set to
            field_name: the field name of the Polarion object to set
        """
        # TODO: Still needs to be fully tested. Looks like there are some bugs.
        csm = self._cls_suds_map[field_name]
        arr_inst = csm.get("arr_cls")()
        obj_inst = csm.get("cls")()
        # obj_attach =
        if not isinstance(val,
                          (list, arr_inst.__class__,
                           arr_inst._suds_object.__class__)):
            raise PyleroLibException(
                "{0}s must be a list of {1}").format(
                    csm["field_name"], obj_inst.__class__.__name__)
        elif not val:
            setattr(
                self._suds_object, csm["field_name"], arr_inst._suds_object)
        elif isinstance(val, arr_inst._suds_object.__class__):
            setattr(self._suds_object, csm["field_name"], val)
        elif isinstance(val, arr_inst.__class__):
            setattr(self._suds_object, csm["field_name"], val._suds_object)
        else:
            if isinstance(val, list):
                # if str values are based in, try instantiating a class with
                # the vals and then using that list. Then continue processing
                if isinstance(val[0], basestring):
                    val[0] = self._check_encode(val[0])
                    val = [csm["cls"](item) for item in val]

                if isinstance(val[0], obj_inst._suds_object.__class__):
                    setattr(getattr(self._suds_object, csm["field_name"]),
                            csm["inner_field_name"], val)
                else:
                    setattr(self._suds_object, csm["field_name"],
                            arr_inst._suds_object)
                    for item in val:
                        getattr(getattr(self._suds_object, csm["field_name"]),
                                csm["inner_field_name"]).append(
                                    item._suds_object)
Exemple #8
0
    def __init__(self,
                 project_id=None,
                 suds_object=None,
                 location=None,
                 uri=None):
        """Project constructor.

        Args:
            project_id: when given, the object is populated with the
                         Project data.
            suds_object: PolarionProject object. When given, the object
                          is populated by object data.
            location: the location of the Polarion project
            uri: the uri that references the PolarionProject

        Notes:
            Either project_id or suds_object or location or uri can be passed
            in or none of them. If none of the identifying parameters are
            passed in an empty object is created

        References:
            Project.getProject
            Project.getProjectatLocation
            Project.getProjectByURI
        """
        super(self.__class__, self).__init__(project_id, suds_object)
        if project_id:
            # if the project is already cached, make a deep copy and use it.
            # If not, get it and add it to the cache.
            project = self._cache["projects"].get(project_id)
            if project:
                self._suds_object = copy.deepcopy(project)
            else:
                self._suds_object = self.session.project_client.service. \
                    getProject(project_id)
                self._cache["projects"][project_id] = self._suds_object
        elif location:
            self._suds_object = self.session.project_client.service. \
                getProjectatLocation(location)
        elif uri:
            self._suds_object = self.session.project_client.service. \
                getProjectByURI(uri)
        if project_id or location or uri:
            if getattr(self._suds_object, "_unresolvable", True):
                raise PyleroLibException("The Project was not found.")
Exemple #9
0
    def get_user_avatar_url(self):
        """method get_user_avatar_url, returns a string with the relative URL
        of the user's avatar.

        Args:
            None

        Notes:
            Raises an error if the User is not populated.

        References:
            Project.getUserAvatarURL
        """
        if self.user_id:
            return self.session.project_client.service.getUserAvatarURL(
                self.user_id)
        else:
            raise PyleroLibException("The user object is empty")
Exemple #10
0
    def _check_encode(self, val):
        """Validate @val is a UTF-8 because Polarion doesn't support not
            UTF-8 characters. The only use case that is not taken into account
            is when an attribute is set directly with a SUDS object. The users
            have no way of calling this function in this case.

            Args:
            val (string): the value that the property is being set to
            """
        try:
            if not isinstance(val, type(u'')):
                val = val.decode('utf-8')
            # replace chr(160) with space
            return val.replace(u'\xa0', u' ')
        except UnicodeError as err:
            raise PyleroLibException(
                'String must be UTF-8 encoded. The following error was '
                'raised when converting it to unicode: {0}'.format(err))
Exemple #11
0
    def update(self):
        """method update, updates Polarion with the User attributes

        Args:
            None

        Notes:
            Raises an error if the User is not populated.

        References:
            p.Project.updateUser
        """
        if self.user_id:
            # self._map_to_suds()
            self.session.project_client.service.updateUser(self._suds_object)
            # CHECK for verification
        else:
            raise PyleroLibException("The user object is empty")
Exemple #12
0
    def _obj_setter(self, val, field_name):
        """set function for attributes that reference an object. It can accept
        a string, a Pylero object or a raw WSDL object. If a string is given,
        it is passed in to the object as its obj_id.

        Args:
            val: the value that the property is being set to
            field_name: the field name of the Polarion object to set
        """
        csm = self._cls_suds_map[field_name]
        suds_field_name = csm["field_name"]
        enum_id = csm.get("enum_id")
        enum_override = csm.get("enum_override", [])
        sync_field = csm.get("sync_field")
        obj_cls = csm.get("cls")
        # deepcopy so that changes do not stick
        add_parms = copy.deepcopy(csm.get("additional_parms", {}))
        if isinstance(val, basestring):
            val = self._check_encode(val)
            if enum_id and val not in enum_override:
                self.check_valid_field_values(
                    val, enum_id, {},
                    self._wi_type if hasattr(self, "_wi_type") else None)
        if not sync_field:
            sync_field = "_suds_object"
        if isinstance(val, basestring) or val is None:
            add_parms[obj_cls._id_field] = val
            obj = obj_cls(**add_parms)
            setattr(self._suds_object, suds_field_name,
                    getattr(obj, sync_field))
        elif isinstance(val, obj_cls):
            setattr(self._suds_object, suds_field_name,
                    getattr(val, sync_field))
        elif isinstance(val, obj_cls()._suds_object.__class__):
            obj = obj_cls()
            if sync_field in obj._cls_suds_map:
                suds_sync_field = obj._cls_suds_map[sync_field]
                # if sync_field is given, the attribute will be simple
                val = getattr(val, suds_sync_field)
            setattr(self._suds_object, suds_field_name, val)
        else:
            raise PyleroLibException("the value {0} is not a valid type".
                                       format(val))
Exemple #13
0
    def remove_plan_items(self, work_items):
        """Remove plan records to the plan.

        Args:
            items: list of work_item_ids

        Returns:
            None

        References:
            Planning.removePlanItems
        """
        self._verify_obj()
        if work_items:
            if not isinstance(work_items, list):
                raise PyleroLibException(
                    "work_items must be a list of _WorkItem objects")
        p_items = []
        for item in work_items:
            wi = _WorkItem(self.project_id, work_item_id=item)
            p_items.append(wi.uri)
        self.session.planning_client.service.removePlanItems(self.uri, p_items)
Exemple #14
0
    def session(cls):
        if not cls.connected:
            cfg = Configuration()
            # if the password is not supplied in the config file, ask the user
            # for it
            if not cfg.pwd:
                cfg.pwd = getpass(
                    "Password not in config file.\nEnter Password:"******"com.polarion.platform.security." \
                            "AuthenticationFailedException" \
                            in e.fault.faultstring:
                        pwd = getpass("Invalid Password.\nEnter Password:"******"Unable to establish pylero session "
                        "due to 3 incorrect login attempts")
            cls.session.default_project = cfg.proj
            cls.session.user_id = cfg.login
            cls.session.password = cfg.pwd
            cls.session.repo = cfg.repo
            # must use try/except instead of or because the config file
            # may return a non empty value, such as " "
        return cls.session
Exemple #15
0
    def create_work_item(self, parent_id, w_item):
        """create a work item in the current document

        Args:
            parent_id: The work_item_id of the parent _WorkItem
            wi: The Work Item object to create.

        Returns:
            The created _WorkItem

        References:
            Tracker.createWorkItemInModule
        """
        self._verify_obj()
        if isinstance(w_item, _WorkItem):
            w_item.verify_required()
            suds_wi = w_item._suds_object
        else:
            raise PyleroLibException(
                "the w_item parameter must be a _WorkItem")
        if parent_id:
            parent_uri = _WorkItem(work_item_id=parent_id,
                                   project_id=self.project_id).uri
        else:
            doc_wis = self.get_work_items(None, False, None)
            if doc_wis:
                parent_uri = doc_wis[0].uri
            else:
                parent_uri = None
            wi_uri = self.session.tracker_client.service. \
                createWorkItemInModule(self.uri, parent_uri, suds_wi)
            new_wi = w_item.__class__(uri=wi_uri)
            new_wi._changed_fields = w_item._changed_fields
            new_wi.update()
            new_wi = _WorkItem(uri=wi_uri)
            return new_wi
Exemple #16
0
    def _custom_setter(self, val, field_name):
        """Works with custom fields that has to keep track of values and what
        changed so that on update it can also update all the custom fields at
        the same time.

        Args:
            val: the value that the property is being set to
            field_name: the field name of the Polarion object to set
        """
        csm = self._cls_suds_map[field_name]
        if field_name == "test_steps":
            if not val:
                self._changed_fields[csm["field_name"]] = None
            elif isinstance(val, csm["cls"]):
                self._changed_fields[csm["field_name"]] = val._suds_object
            elif isinstance(val, csm["cls"]()._suds_object.__class__):
                self._changed_fields[csm["field_name"]] = val
            else:
                raise PyleroLibException(
                    "The value must be a {0}".format(csm["cls"].__name__))
        # move the custom fields to within the object, otherwise each custom
        # field is a seperate SVN commit. testSteps, does not work unless it
        # is uploaded using the set_test_steps function.
        else:
            cust = self.custom_obj()
            cust.key = csm["field_name"]
            if val is None:
                cust.value = None
            elif (not csm.get("cls") or isinstance(val, basestring)) \
                    and not csm.get("is_array"):
                # if there is no cls specified, val can be a bool, int, ...
                # if val is a string, it may be used to instantiate the class
                if isinstance(val, basestring):
                    val = self._check_encode(val)
                if csm.get("enum_id") and \
                        val not in csm.get("enum_override", []):
                    # uses deepcopy, to not affect other instances of the class
                    additional_parms = copy.deepcopy(
                        csm.get("additional_parms", {}))
                    self.check_valid_field_values(val, csm.get("enum_id"),
                                                  additional_parms,
                                                  csm.get("control"))
                cust.value = csm["cls"](val)._suds_object if csm.get("cls") \
                    else val
            elif csm.get("is_array"):
                if not isinstance(val, list):
                    raise PyleroLibException("value must be a list")
                if csm.get("enum_id"):
                    cust.value = csm["cls"]()._suds_object
                    for i in val:
                        if i not in csm.get("enum_override", []):
                            # uses deepcopy, to not affect other instances
                            # of the class
                            additional_parms = copy.deepcopy(
                                csm.get("additional_parms", {}))
                            self.check_valid_field_values(
                                i, csm.get("enum_id"), additional_parms,
                                self._wi_type if hasattr(self,"_wi_type")
                                else None)
                        cust.value[0].append(
                            csm["cls"]._cls_inner(i)._suds_object)

            elif isinstance(val, csm["cls"]):
                cust.value = val._suds_object
            elif isinstance(val, csm["cls"]()._suds_object.__class__):
                cust.value = val
            else:
                raise PyleroLibException(
                    "The value must be of type {0}."
                    .format(csm["cls"].__name__))
            if "customFields" not in self._suds_object:
                self._suds_object.customFields = self.custom_array_obj()
            cf = self._suds_object.customFields[0]
            if cf:
                # check if the custom field already exists and modify it.
                match = [x for x in cf if x.key == csm["field_name"]]
                if match:
                    match[0].value = cust.value
                else:
                    cf.append(cust)
                    self._custom_fields = cf
            else:
                self._custom_fields = [cust]
Exemple #17
0
    def __init__(self, obj_id=None, suds_object=None):
        # cls_suds_map must be available for some parameters on the class
        # level, but gets changed on the instance level and those changes
        # should not be accessible to other instances. This is the reason
        # for overwriting it as an instance attribute.
        self._cls_suds_map = copy.deepcopy(self._cls_suds_map)
        # _fix_circular_refs is a function that allows objects to contain
        # circular references by applying the reference only after the class
        # has been instantiated. Some objects contain references to themselves,
        # for example a parent attribute.
        if hasattr(self, "_fix_circular_refs"):
            self._fix_circular_refs()
        # if _id_field has not been set in the child class, the obj_id field
        # cannot be passed as a parameter.
        if obj_id and not self._id_field:
            raise PyleroLibException(
                "{0} only accepts a suds object, not an obj_id".format(
                    self.__class__.__name))
        if suds_object:
            self._suds_object = suds_object
        else:
            self._get_suds_object()
        # initialize all instance attributes as properties
        # check if the property already exists. If so, use existing.
        for key in list(self._cls_suds_map.keys()):
            if not hasattr(self.__class__, key):
                # require default values for lambda or it evaluates all
                # variables
                # at the end of function (self._cls_suds_map[key] was evaluated
                # as the last key value in the for loop for all defined lambdas
                # Property Builder, parses _cls_suds_map to build properties:
                # custom fields:
                #    getter has parameters:
                #        field_name
                #    setter has parameters:
                #        val: the value that the property is set to
                #        field_name
                # array object fields:
                #    getter has parameters:
                #        field_name
                #    setter has parameters:
                #        val: the value that the property is set to
                #        field_name
                # object fields:
                #    getter has parameters:
                #        field_name
                #    setter has parameters:
                #        val: the value that the property is set to
                #        field_name
                # regular fields;
                #    use getattr and setattr
                if isinstance(self._cls_suds_map[key], dict):
                    if "is_custom" in self._cls_suds_map[key]:
                        setattr(self.__class__, key, property(
                            lambda self, field_name=key:
                                self._custom_getter(field_name),
                            lambda self, val, field_name=key:
                                self._custom_setter(val, field_name)))
                    elif "is_array" in self._cls_suds_map[key]:
                        setattr(self.__class__, key, property(
                            lambda self, field_name=key:
                                self._arr_obj_getter(field_name),
                            lambda self, val, field_name=key:
                                self._arr_obj_setter(val, field_name)))
                    else:
                        setattr(self.__class__, key, property(
                            lambda self, field_name=key:
                                self._obj_getter(field_name),
                            lambda self, val, field_name=key:
                                self._obj_setter(val, field_name)))
                else:
                    setattr(self.__class__, key, property(
                        # if the attribute doesn't exist in the current object
                        # return None
                        lambda self, suds_key=self._cls_suds_map[key]:
                            getattr(self._suds_object, suds_key, None),
                        lambda self, value, suds_key=self._cls_suds_map[key]:
                            self._regular_setter(value, suds_key)))
# after all properties are defined set the id field to the value passed in.
        if obj_id is not None:
            setattr(self, self._id_field, obj_id)
Exemple #18
0
    def create(cls, project_id, space, document_name, document_title,
               allowed_wi_types,
               document_type,
               structure_link_role="parent",
               home_page_content=""):
                # There is no document object.
        # don't know what to do with the URI it returns.
        """class method create Creates a document or an old-style
        Module/Document in given location with given parameters.

        Args:
            project_id: project to create module in
            space: document space location with one component or None for
                   default space
            document_name: Document name (required)
            document_title: Document title (required)
            allowed_wi_types: list of types, only one should be specified
            document_type: Type of document (required i.e testspecification).
            structure_link_role: required, role which defines the hierarchy of
                                 work items inside the Module, default: parent
            home_page_content: HTML markup for document home page, default ""

        Returns:
            None

        References:
            Tracker.createDocument
        """
        if isinstance(allowed_wi_types, basestring):
            allowed_wi_types = [allowed_wi_types]
        awit = [EnumOptionId(item)._suds_object
                for item in allowed_wi_types]
        slr = EnumOptionId(structure_link_role)._suds_object
        try:
            uri = cls.session.tracker_client.service.createDocument(
                project_id, space, document_name, document_title, awit,
                slr, home_page_content)
            doc = Document(uri=uri)
            doc.type = document_type
            # for some reason, when in a tx (@tx_wrapper), the
            # returned doc does not include the home_page_content attribute
            # so it must be reset before the update. If it is not set, an
            # exception is raised:
            # "java.lang.IllegalArgumentException: Content can't be null"
            if not doc.home_page_content:
                doc.home_page_content = home_page_content
            doc.update()
            if not home_page_content:
                # create heading work item for each document
                wi_head = _WorkItem()
                wi_head.type = "heading"
                wi_head.title = document_title
                doc.create_work_item(None, wi_head)
            return doc
        except suds.WebFault as e:
            if "Invalid document on location Location" in e.fault.faultstring:
                raise PyleroLibException(
                    "Document {0}/{1} already exists".format(space,
                                                             document_name))
            else:
                raise PyleroLibException(e.fault)