def test_unique(self):
        job = Job()
        tagA = Tag()
        tagB = Tag()
        tagA.jobs = [job]
        tagA.tag = "foo0"
        tagB.jobs = [job]
        tagB.tag = "foo1"
        db.session.add_all([job, tagA, tagB])

        with self.assertRaises(DatabaseError):
            db.session.commit()
    def test_insert(self):
        # A job can not be created without a jobtype, create one first
        jobtype = JobType()
        jobtype.name = "foo"
        jobtype.description = "this is a job type"
        jobtype_version = JobTypeVersion()
        jobtype_version.jobtype = jobtype
        jobtype_version.version = 1
        jobtype_version.classname = "Foobar"
        jobtype_version.code = ("""
            class Foobar(JobType):
                pass""").encode("utf-8")
        db.session.add(jobtype_version)

        queue = JobQueue()
        queue.name = "FooQueue"

        job = Job()
        job.title = "Test Job"
        job.jobtype_version = jobtype_version
        job.queue = queue

        tag = Tag()
        tag.jobs = [job]
        tag.tag = "foo456"
        db.session.add_all([tag, job])
        db.session.commit()
        model_id = tag.id
        job_id = job.id
        db.session.remove()
        result = Tag.query.filter_by(id=model_id).first()
        self.assertEqual(result.tag, "foo456")
        self.assertEqual(result.jobs[0].id, job_id)
    def test_insert(self):
        # A job can not be created without a jobtype, create one first
        jobtype = JobType()
        jobtype.name = "foo"
        jobtype.description = "this is a job type"
        jobtype.classname = "Foobar"
        jobtype.code = dedent("""
        class Foobar(JobType):
            pass""").encode("utf-8")
        jobtype.mode = JobTypeLoadMode.OPEN
        db.session.add(jobtype)

        job = Job()
        job.job_type = jobtype
        tag = Tag()
        tag.jobs = [job]
        tag.tag = "foo456"
        db.session.add_all([tag, job])
        db.session.commit()
        model_id = tag.id
        job_id = job.id
        db.session.remove()
        result = Tag.query.filter_by(id=model_id).first()
        self.assertEqual(result.tag, "foo456")
        self.assertEqual(result.jobs[0].id, job_id)
Ejemplo n.º 4
0
    def put(self, tagname=None):
        """
        A ``PUT`` to this endpoint will create a new tag under the given URI.
        If a tag already exists under that URI, it will be deleted, then
        recreated.
        Note that when overwriting a tag like that, all relations that are not
        explicitly specified here will be deleted
        You can optionally specify a list of agents or jobs relations as
        integers in the request data.

        You should only call this by id for overwriting an existing tag or if you
        have a reserved tag id. There is currently no way to reserve a tag id.

        .. http:put:: /api/v1/tags/<str:tagname> HTTP/1.1

            **Request**

            .. sourcecode:: http

                PUT /api/v1/tags/interesting HTTP/1.1
                Accept: application/json

                {
                    "tag": "interesting"
                }

            **Response**

            .. sourcecode:: http

                HTTP/1.1 201 CREATED
                Content-Type: application/json

                {
                    "id": 1,
                    "tag": "interesting"
                }

            **Request**

            .. sourcecode:: http

                PUT /api/v1/tags/interesting HTTP/1.1
                Accept: application/json

                {
                    "tag": "interesting",
                    "agents": [1]
                    "jobs": []
                }

            **Response**

            .. sourcecode:: http

                HTTP/1.1 201 CREATED
                Content-Type: application/json

                {
                    "id": 1,
                    "tag": "interesting"
                }

        :statuscode 201: a new tag was created
        :statuscode 400: there was something wrong with the request (such as
                            invalid columns being included)
        :statuscode 404: a referenced agent or job does not exist
        """
        if isinstance(tagname, int):
            tag = Tag.query.filter_by(id=tagname).first()

            if "tag" in g.json and g.json["tag"] != tag.tag:
                error = "tag name retrieved for %s does not match tag " \
                        "name in request" % tagname
                return jsonify(error=error), BAD_REQUEST

            g.json.setdefault("tag", tag.tag)

        elif isinstance(tagname, STRING_TYPES):
            g.json.setdefault("tag", tagname)

            if g.json["tag"] != tagname:
                return jsonify(error="`tag` in data must be equal to the "
                                     "tag in the requested url"), BAD_REQUEST
            tag = Tag.query.filter_by(tag=g.json["tag"]).first()

        # If tag exists, delete it before recreating it
        if tag:
            logger.debug(
                "tag %s will be replaced with %r on commit", tag.tag, g.json)
            db.session.delete(tag)
            db.session.flush()

        agents = []
        if "agents" in g.json:
            agent_ids = g.json.pop("agents", [])

            if not isinstance(agent_ids, list):
                return jsonify(error="agents must be a list"), BAD_REQUEST

            try:
                agent_ids = list(map(UUID, agent_ids))
            except (ValueError, AttributeError):
                return jsonify(error="All agent ids must be UUIDs"), BAD_REQUEST

            # find all models matching the request id(s)
            agents = Agent.query.filter(Agent.id.in_(agent_ids)).all()

            # make sure all those ids were actually found
            missing_agents = set(agent_ids) - set(agent.id for agent in agents)
            if missing_agents:
                return jsonify(
                    error="agent(s) not found: %s" % missing_agents), NOT_FOUND

        jobs = []
        if "jobs" in g.json:
            job_ids = g.json.pop("jobs", [])

            if not isinstance(job_ids, list):
                return jsonify(error="jobs must be a list"), BAD_REQUEST

            # make sure all ids provided are ints
            if not all(isinstance(job_id, int) for job_id in job_ids):
                return jsonify(
                    error="all job ids must be integers"), BAD_REQUEST

            # find all models matching the request id(s)
            jobs = Job.query.filter(Agent.id.in_(job_ids)).all()

            # make sure all those ids were actually found
            missing_jobs = set(job_ids) - set(job.id for job in jobs)
            if missing_jobs:
                return jsonify(
                    error="job(s) not found: %s" % missing_jobs), NOT_FOUND

        new_tag = Tag(**g.json)
        if isinstance(tagname, int):
            new_tag.id = tagname
        new_tag.agents = agents
        new_tag.jobs = jobs

        logger.info("creating tag %s: %r", new_tag.tag, new_tag.to_dict())
        db.session.add(new_tag)
        db.session.commit()

        return (jsonify(new_tag.to_dict(unpack_relationships=("agents", "jobs"))),
                CREATED)