Пример #1
0
    def _fetch(self, inject=None):
        """ Get the missing test plan type data """
        Nitrate._fetch(self, inject)

        # Directly fetch from the initial object dict
        if inject is not None:
            log.info("Processing PlanType ID#{0} inject".format(inject["id"]))
        # Search by test plan type id
        elif self._id is not NitrateNone:
            try:
                log.info("Fetching test plan type " + self.identifier)
                inject = self._server.TestPlan.get_plan_type(self.id)
            except xmlrpclib.Fault as error:
                log.debug(error)
                raise NitrateError(
                        "Cannot find test plan type for " + self.identifier)
        # Search by test plan type name
        else:
            try:
                log.info(u"Fetching test plan type '{0}'".format(self.name))
                inject = self._server.TestPlan.check_plan_type(self.name)
            except xmlrpclib.Fault as error:
                log.debug(error)
                raise NitrateError("PlanType '{0}' not found".format(
                        self.name))
        # Initialize data from the inject and index into cache
        log.debug("Initializing PlanType ID#{0}".format(inject["id"]))
        log.data(pretty(inject))
        self._inject = inject
        self._id = inject["id"]
        self._name = inject["name"]
        self._index(self.name)
Пример #2
0
    def _fetch(self, inject=None):
        """ Fetch user data from the server """
        Nitrate._fetch(self, inject)

        if inject is None:
            # Search by id
            if self._id is not NitrateNone:
                try:
                    log.info("Fetching user " + self.identifier)
                    inject = self._server.User.filter({"id": self.id})[0]
                except IndexError:
                    raise NitrateError(
                            "Cannot find user for " + self.identifier)
            # Search by login
            elif self._login is not NitrateNone:
                try:
                    log.info(
                            "Fetching user for login '{0}'".format(self.login))
                    inject = self._server.User.filter(
                            {"username": self.login})[0]
                except IndexError:
                    raise NitrateError("No user found for login '{0}'".format(
                            self.login))
            # Search by email
            elif self._email is not NitrateNone:
                try:
                    log.info("Fetching user for email '{0}'".format(
                            self.email))
                    inject = self._server.User.filter({"email": self.email})[0]
                except IndexError:
                    raise NitrateError("No user found for email '{0}'".format(
                            self.email))
            # Otherwise initialize to the current user
            else:
                log.info("Fetching the current user")
                inject = self._server.User.get_me()
                self._index("i-am-current-user")

        # Initialize data from the inject and index into cache
        log.debug("Initializing user UID#{0}".format(inject["id"]))
        log.data(pretty(inject))
        self._inject = inject
        self._id = inject["id"]
        self._login = inject["username"]
        self._email = inject["email"]
        if inject["first_name"] and inject["last_name"]:
            self._name = inject["first_name"] + " " + inject["last_name"]
        else:
            self._name = None
        self._index(self.login, self.email)
Пример #3
0
 def __init__(self, status):
     """
     Takes numeric status id (1-8) or status name which is one of:
     IDLE, PASSED, FAILED, RUNNING, PAUSED, BLOCKED, ERROR, WAIVED
     """
     if isinstance(status, int):
         if status < 1 or status > 8:
             raise NitrateError(
                     "Not a valid Status id: '{0}'".format(status))
         self._id = status
     else:
         try:
             self._id = self._statuses.index(status)
         except ValueError:
             raise NitrateError("Invalid status '{0}'".format(status))
Пример #4
0
    def __init__(self, id=None, name=None, product=None, **kwargs):
        """ Initialize by component id or component name and product """

        # Initialize (unless already done)
        id, ignore, inject, initialized = self._is_initialized(id)
        if initialized: return
        Nitrate.__init__(self, id)

        # If inject given, fetch component data from it
        if inject:
            self._fetch(inject)
        # Initialized by product and component name
        elif name is not None and product is not None:
            # Detect product format
            if isinstance(product, Product):
                self._product = product
            else:
                self._product = Product(product)
            self._name = name
            # Index by name-product (only when the product name is known)
            if self.product._name is not NitrateNone:
                self._index("{0}---in---{1}".format(
                        self.name, self.product.name))
        # Otherwise just check that the id was provided
        elif id is None:
            raise NitrateError("Need either component id or both product "
                    "and component name to initialize the Component object.")
Пример #5
0
def _idify(id):
    """
    Pack/unpack multiple ids into/from a single id

    List of ids is converted into a single id. Single id is converted
    into list of original ids. For example:

        _idify([1, 2]) ---> 1000000002
        _idify(1000000002) ---> [1, 2]

    This is used for indexing by fake internal id.
    """
    if isinstance(id, list):
        result = 0
        for value in id:
            result = result * config._MAX_ID + value
        return result
    elif isinstance(id, int):
        result = []
        while id > 0:
            remainder = id % config._MAX_ID
            id = id // config._MAX_ID
            result.append(int(remainder))
        result.reverse()
        return result
    else:
        raise NitrateError("Invalid id for idifying: '{0}'".format(id))
Пример #6
0
    def __init__(self, id=None, name=None, product=None, **kwargs):
        """ Initialize by build id or product and build name """

        # Backward compatibility for 'build' argument (now called 'name')
        name = name if name is not None else kwargs.get("build")

        # Initialize (unless already done)
        id, ignore, inject, initialized = self._is_initialized(id or name)
        if initialized: return
        Nitrate.__init__(self, id)

        # If inject given, fetch build data from it
        if inject:
            self._fetch(inject)
        # Initialized by build name and product
        elif name is not None and product is not None:
            self._name = name
            # Detect product format
            if isinstance(product, Product):
                self._product = product
            else:
                self._product = Product(product)
            # Index by name-product (only when the product name is known)
            if self.product._name is not NitrateNone:
                self._index("{0}---in---{1}".format(
                        self.name, self.product.name))
        # Otherwise just check that the id was provided
        elif not id:
            raise NitrateError("Need either build id or both build name "
                    "and product to initialize the Build object.")
Пример #7
0
 def __init__(self, casestatus):
     """
     Takes numeric status id (1-4) or status name which is one of:
     PROPOSED, CONFIRMED, DISABLED, NEED_UPDATE
     """
     if isinstance(casestatus, int):
         if casestatus < 1 or casestatus > 4:
             raise NitrateError(
                     "Not a valid casestatus id: '{0}'".format(casestatus))
         self._id = casestatus
     else:
         try:
             self._id = self._casestatuses.index(casestatus)
         except ValueError:
             raise NitrateError(
                     "Invalid casestatus '{0}'".format(casestatus))
Пример #8
0
    def __init__(self, id=None, name=None):
        """
        Initialize the Product by id or name

        Examples:

        Product(60)
        Product(id=60)
        Product("Red Hat Enterprise Linux 6")
        Product(name="Red Hat Enterprise Linux 6")
        """

        # Initialize (unless already done)
        id, name, inject, initialized = self._is_initialized(id or name)
        if initialized: return
        Nitrate.__init__(self, id)

        # If inject given, fetch test case data from it
        if inject:
            self._fetch(inject)
        # Initialize by name
        elif name is not None:
            self._name = name
            self._index(name)
        # Otherwise just check that the product id was provided
        elif not id:
            raise NitrateError("Need id or name to initialize Product")
Пример #9
0
    def __init__(self, priority):
        """
        Takes numeric priority id (1-5) or priority name which is one of:
        P1, P2, P3, P4, P5
        """

        if isinstance(priority, int):
            if priority < 1 or priority > 5:
                raise NitrateError(
                        "Not a valid Priority id: '{0}'".format(priority))
            self._id = priority
        else:
            try:
                self._id = self._priorities.index(priority)
            except ValueError:
                raise NitrateError("Invalid priority '{0}'".format(priority))
Пример #10
0
    def __init__(self, id=None, name=None, product=None, **kwargs):
        """ Initialize by version id or product and version """

        # Backward compatibility for 'version' argument (now called 'name')
        name = name if name is not None else kwargs.get("version")

        # Initialize (unless already done)
        id, ignore, inject, initialized = self._is_initialized(id)
        if initialized: return
        Nitrate.__init__(self, id)

        # If inject given, fetch tag data from it
        if inject:
            self._fetch(inject)
        # Initialize by version name and product
        elif name is not None and product is not None:
            self._name = name
            # Convert product into object if necessary
            if isinstance(product, Product):
                self._product = product
            else:
                self._product = Product(product)
            # Index by name/product (but only when the product name is known)
            if self.product._name is not NitrateNone:
                self._index("{0}---in---{1}".format(
                        self.name, self.product.name))
        # Otherwise just make sure the version id was provided
        elif not id:
            raise NitrateError("Need either version id or both product "
                    "and version name to initialize the Version object.")
Пример #11
0
    def __init__(self):
        """ Initialize the configuration """
        # Nothing to do if already parsed
        if self._parsed:
            return

        class Section(object):
            """ Trivial class for sections """

        # Try system settings when the config does not exist in user directory
        if not os.path.exists(self.path):
            log.debug("User config file not found, trying /etc/nitrate.conf")
            self.path = "/etc/nitrate.conf"
        if not os.path.exists(self.path):
            log.error(self.example)
            raise NitrateError("No config file found")
        log.debug("Parsing config file {0}".format(self.path))

        # Parse the config
        try:
            parser = ConfigParser.SafeConfigParser()
            parser.read([self.path])
            for section in parser.sections():
                # Create a new section object for each section
                setattr(self, section, Section())
                # Set its attributes to section contents (adjust types)
                for name, value in parser.items(section):
                    try:
                        value = int(value)
                    except ValueError:
                        pass
                    if value == "True":
                        value = True
                    if value == "False":
                        value = False
                    setattr(getattr(self, section), name, value)
        except ConfigParser.Error:
            log.error(self.example)
            raise NitrateError("Cannot read the config file")

        # Make sure the server URL is set
        try:
            self.nitrate.url is not None
        except AttributeError:
            log.error(self.example)
            raise NitrateError("No url found in the config file")
        self._parsed = True
Пример #12
0
    def _fetch(self, inject=None):
        """ Get the missing build data """
        Nitrate._fetch(self, inject)
        # Directly fetch from the initial object dict
        if inject is not None:
            log.info("Processing build ID#{0} inject".format(
                    inject["build_id"]))
        # Search by build id
        elif self._id is not NitrateNone:
            try:
                log.info("Fetching build " + self.identifier)
                inject = self._server.Build.get(self.id)
            except xmlrpclib.Fault as error:
                log.debug(error)
                raise NitrateError(
                        "Cannot find build for " + self.identifier)
        # Search by build name and product
        else:
            try:
                log.info(u"Fetching build '{0}' of '{1}'".format(
                        self.name, self.product.name))
                inject = self._server.Build.check_build(
                        self.name, self.product.id)
                self._id = inject["build_id"]
            except xmlrpclib.Fault as error:
                log.debug(error)
                raise NitrateError("Build '{0}' not found in '{1}'".format(
                    self.name, self.product.name))
            except KeyError:
                if "args" in inject:
                    log.debug(inject["args"])
                raise NitrateError("Build '{0}' not found in '{1}'".format(
                    self.name, self.product.name))

        # Initialize data from the inject and index into cache
        log.debug("Initializing Build ID#{0}".format(inject["build_id"]))
        log.data(pretty(inject))
        self._inject = inject
        self._id = inject["build_id"]
        self._name = inject["name"]
        self._product = Product(
                {"id": inject["product_id"], "name": inject["product"]})
        self._index("{0}---in---{1}".format(self.name, self.product.name))
Пример #13
0
 def __eq__(self, other):
     """ Objects are compared based on their id """
     # Special handling for comparison with None
     if other is None:
         return False
     # We can only compare objects of the same type
     if self.__class__ != other.__class__:
         raise NitrateError("Cannot compare '{0}' with '{1}'".format(
             self.__class__.__name__, other.__class__.__name__))
     return self.id == other.id
Пример #14
0
    def __init__(self, status):
        """
        Takes bool, numeric status id or status name.

        0 ... False ... DISABLED
        1 ... True .... ENABLED
        """

        if isinstance(status, int):
            if not status in [0, 1]:
                raise NitrateError(
                        "Not a valid plan status id: '{0}'".format(status))
            # Save id (and convert possible bool to int)
            self._id = int(status)
        else:
            try:
                self._id = self._statuses.index(status)
            except ValueError:
                raise NitrateError("Invalid plan status '{0}'".format(status))
Пример #15
0
    def _fetch(self, inject=None):
        """ Fetch version data from the server """
        Nitrate._fetch(self, inject)

        # Directly fetch from the initial object dict
        if inject is not None:
            log.debug("Processing Version ID#{0} inject".format(inject["id"]))
        # Search by version id
        elif self._id is not NitrateNone:
            try:
                log.info("Fetching version {0}".format(self.identifier))
                inject = self._server.Product.filter_versions(
                        {'id': self.id})[0]
            except IndexError:
                raise NitrateError(
                        "Cannot find version for {0}".format(self.identifier))
        # Search by product and name
        else:
            try:
                log.info(u"Fetching version '{0}' of '{1}'".format(
                        self.name, self.product.name))
                inject = self._server.Product.filter_versions(
                        {'product': self.product.id, 'value': self.name})[0]
            except IndexError:
                raise NitrateError(
                        "Cannot find version for '{0}'".format(self.name))
        # Initialize data from the inject and index into cache
        log.debug("Initializing Version ID#{0}".format(inject["id"]))
        log.data(pretty(inject))
        self._inject = inject
        self._id = inject["id"]
        self._name = inject["value"]
        self._product = Product(inject["product_id"])
        # Index by product name & version name (if product is cached)
        if self.product._name is not NitrateNone:
            self._index("{0}---in---{1}".format(self.name, self.product.name))
        # Otherwise index by id only
        else:
            self._index()
Пример #16
0
    def __init__(self, status):
        """
        Takes numeric status id, status name or stop date.

        A 'None' value is considered to be a 'no stop date' running:

        0 ... RUNNING  ... 'None'
        1 ... FINISHED ... '2011-07-27 15:14'
        """
        if isinstance(status, int):
            if status not in [0, 1]:
                raise NitrateError(
                        "Not a valid run status id: '{0}'".format(status))
            self._id = status
        else:
            # Running or no stop date
            if status == "RUNNING" or status == "None" or status is None:
                self._id = 0
            # Finished or some stop date
            elif status == "FINISHED" or re.match("^[-0-9: ]+$", status):
                self._id = 1
            else:
                raise NitrateError("Invalid run status '{0}'".format(status))
Пример #17
0
    def _fetch(self, inject=None):
        """ Get the missing category data """
        Nitrate._fetch(self, inject)

        # Directly fetch from the initial object dict
        if inject is not None:
            log.info("Processing category ID#{0} inject".format(inject["id"]))
        # Search by category id
        elif self._id is not NitrateNone:
            try:
                log.info("Fetching category {0}".format(self.identifier))
                inject = self._server.Product.get_category(self.id)
            except xmlrpclib.Fault as error:
                log.debug(error)
                raise NitrateError(
                        "Cannot find category for " + self.identifier)
        # Search by category name and product
        else:
            try:
                log.info(u"Fetching category '{0}' of '{1}'".format(
                        self.name, self.product.name))
                inject = self._server.Product.check_category(
                        self.name, self.product.id)
            except xmlrpclib.Fault as error:
                log.debug(error)
                raise NitrateError("Category '{0}' not found in"
                        " '{1}'".format(self.name, self.product.name))

        # Initialize data from the inject and index into cache
        log.debug("Initializing category ID#{0}".format(inject["id"]))
        log.data(pretty(inject))
        self._inject = inject
        self._id = inject["id"]
        self._name = inject["name"]
        self._product = Product(
                {"id": inject["product_id"], "name": inject["product"]})
        self._index("{0}---in---{1}".format(self.name, self.product.name))
Пример #18
0
    def _fetch(self, inject=None):
        """ Fetch tag data from the server """
        Nitrate._fetch(self, inject)

        # Directly fetch from the initial object dict
        if inject is not None:
            log.debug("Initializing Tag ID#{0}".format(inject["id"]))
            log.data(pretty(inject))
            self._id = inject["id"]
            self._name = inject["name"]
        # Search by tag id
        elif self._id is not NitrateNone:
            try:
                log.info("Fetching tag " + self.identifier)
                inject = self._server.Tag.get_tags({'ids': [self.id]})
                log.debug("Initializing tag " + self.identifier)
                log.data(pretty(inject))
                self._inject = inject
                self._name = inject[0]["name"]
            except IndexError:
                raise NitrateError(
                        "Cannot find tag for {0}".format(self.identifier))
        # Search by tag name
        else:
            try:
                log.info(u"Fetching tag '{0}'".format(self.name))
                inject = self._server.Tag.get_tags({'names': [self.name]})
                log.debug(u"Initializing tag '{0}'".format(self.name))
                log.data(pretty(inject))
                self._inject = inject
                self._id = inject[0]["id"]
            except IndexError:
                raise NitrateError(
                        "Cannot find tag '{0}'".format(self.name))
        # Index the fetched object into cache
        self._index(self.name)
Пример #19
0
    def _fetch(self, inject=None):
        """ Fetch product data from the server """
        Nitrate._fetch(self, inject)

        # Directly fetch from the initial object dict
        if inject is not None:
            log.debug("Initializing Product ID#{0}".format(inject["id"]))
            log.data(pretty(inject))
            self._id = inject["id"]
            self._name = inject["name"]
        # Search by product id
        elif self._id is not NitrateNone:
            try:
                log.info("Fetching product " + self.identifier)
                inject = self._server.Product.filter({'id': self.id})[0]
                log.debug("Initializing product " + self.identifier)
                log.data(pretty(inject))
                self._inject = inject
                self._name = inject["name"]
            except IndexError:
                raise NitrateError(
                        "Cannot find product for " + self.identifier)
        # Search by product name
        else:
            try:
                log.info(u"Fetching product '{0}'".format(self.name))
                inject = self._server.Product.filter({'name': self.name})[0]
                log.debug(u"Initializing product '{0}'".format(self.name))
                log.data(pretty(inject))
                self._inject = inject
                self._id = inject["id"]
            except IndexError:
                raise NitrateError(
                        "Cannot find product for '{0}'".format(self.name))
        # Index the fetched object into cache
        self._index(self.name)
Пример #20
0
 def set(self, mode=None):
     """ Set the coloring mode """
     # Detect from the environment if no mode given (only once)
     if mode is None:
         # Nothing to do if already detected
         if self._mode is not None:
             return
         # Detect from the environment variable COLOR
         try:
             mode = int(os.environ["COLOR"])
         except Exception:
             mode = COLOR_AUTO
     elif mode < 0 or mode > 2:
         raise NitrateError("Invalid color mode '{0}'".format(mode))
     self._mode = mode
     log.debug("Coloring {0} ({1})".format(
         "enabled" if self.enabled() else "disabled",
         self.MODES[self._mode]))
Пример #21
0
    def __init__(self, id=None, prefix="ID"):
        """ Initialize the object id, prefix and internal attributes """
        # Set up the prefix
        self._prefix = prefix
        # Initialize internal attributes and reset the fetch timestamp
        self._init()

        # Check and set the object id
        if id is None:
            self._id = NitrateNone
        elif isinstance(id, int):
            self._id = id
        else:
            try:
                self._id = int(id)
            except ValueError:
                raise NitrateError("Invalid {0} id: '{1}'".format(
                        self.__class__.__name__, id))
Пример #22
0
    def __init__(self, id=None, name=None):
        """ Initialize by test plan type id or name """

        # Initialize (unless already done)
        id, name, inject, initialized = self._is_initialized(id or name)
        if initialized: return
        Nitrate.__init__(self, id)

        # If inject given, fetch data from it
        if inject:
            self._fetch(inject)
        # Initialize by name
        elif name is not None:
            self._name = name
            self._index(name)
        # Otherwise just check that the test plan type id was provided
        elif not id:
            raise NitrateError(
                    "Need either id or name to initialize the PlanType object")
Пример #23
0
    def __init__(self, id=None, bug=None, system=1, **kwargs):
        """
        Initialize the bug

        Provide external bug id, optionally bug system (Bugzilla by default).
        """

        # Initialize (unless already done)
        id, ignore, inject, initialized = self._is_initialized(id)
        if initialized: return
        Nitrate.__init__(self, id, prefix="BUG")

        # If inject given, fetch bug data from it
        if inject:
            self._fetch(inject)
        # Initialized by bug id and system id
        elif bug is not None and system is not None:
            self._bug = bug
            self._system = system
        # Otherwise just check that the id was provided
        elif id is None:
            raise NitrateError("Need bug id to initialize the Bug object.")
Пример #24
0
 def set(self, level=None):
     """ Set the caching level """
     # Setup from the environment or config file (performed only once)
     if level is None:
         # Default cache level already detected, nothing to do
         if self._level is not None:
             return
         # Attempt to detect the level from the environment
         try:
             self._level = int(os.environ["CACHE"])
         except Exception:
             # Inspect the [cache] section of the config file
             try:
                 self._level = Config().cache.level
             # Use default if no cache section or no config file
             except AttributeError:
                 self._level = CACHE_OBJECTS
     elif level >= CACHE_NONE and level <= CACHE_PERSISTENT:
         self._level = level
     else:
         raise NitrateError("Invalid cache level '{0}'".format(level))
     log.debug("Caching on level {0} ({1})".format(
         self._level, self.LEVELS[self._level]))
Пример #25
0
 def _remove(self, caseruns):
     """ Removing supported by TestRun.testcases.remove() """
     raise NitrateError(
         "Use TestRun.testcases.remove([testcases]) to remove cases")
Пример #26
0
 def _add(self, caseruns):
     """ Adding supported by CaseRun() or TestRun.testcases.add() """
     raise NitrateError(
         "Use TestRun.testcases.add([testcases]) to add new test cases")
Пример #27
0
 def _remove(self, testruns):
     """ Currently no support for removing test runs from test plans """
     raise NitrateError("Sorry, no support for removing test runs yet")
Пример #28
0
 def _add(self, testruns):
     """ New test runs are created using TestRun() constructor """
     raise NitrateError(
         "Use TestRun(testplan=X) for creating a new test run")
Пример #29
0
 def _remove(self, items):
     """ Remove provided items from the server """
     raise NitrateError("To be implemented by respective class.")
Пример #30
0
 def _add(self, items):
     """ Add provided items to the server """
     raise NitrateError("To be implemented by respective class.")