Example #1
0
    def get(self):
        pushid = core.util.get_int_arg(self.request, 'push')
        ping_action = core.util.get_str_arg(self.request, 'action')
        response = yield tornado.gen.Task(
                        self.async_api_call,
                        "push",
                        {"id": pushid}
                    )

        push = self.get_api_results(response)
        if not push:
            self.send_error()

        pings = set(x for x in (push['extra_pings'] or "").split(',') if x)
        if ping_action == 'set':
            pings.add(self.current_user)
        else:
            pings.discard(self.current_user)

        # This is not atomic, so we could theoretically
        # run into race conditions here, but since we're
        # working at machine speed on human input triggers
        # it should be okay for now.
        query = db.push_pushes.update().where(
            db.push_pushes.c.id == pushid,
        ).values({
            'extra_pings': ','.join(pings),
        })
        db.execute_cb(query, self.on_update_complete)
    def test_removerequest(self):
        results = []

        def on_db_return(success, db_results):
            assert success
            results.extend(db_results.fetchall())

        with nested(
            mock.patch.dict(db.Settings, T.MockedSettings),
            mock.patch.object(
                RemoveRequestServlet,
                "get_current_user",
                return_value="testuser"
            )
        ):
            results = []
            db.execute_cb(db.push_pushcontents.select(), on_db_return)
            num_results_before = len(results)

            uri = "/removerequest?request=1&push=1"
            response = self.fetch(uri)
            T.assert_equal(response.error, None)

            results = []
            db.execute_cb(db.push_pushcontents.select(), on_db_return)
            num_results_after = len(results)

            T.assert_equal(num_results_after, num_results_before - 1, "Request removal failed.")
Example #3
0
    def post(self):
        if not self.current_user:
            return self.send_error(403)
        self.requestid = self._arg('request-id')
        self.tag_list = [x for x in TAGS_RE.findall(self._arg('request-tags')) if x]

        reviewid = self._arg('request-review')
        if reviewid:
            try:
                reviewid = int(reviewid)
            except (ValueError, TypeError):
                return self.send_error(500)

        watchers = ','.join(map(str.strip, self._arg('request-watchers').split(',')))

        if self.requestid != '':
            self.requestid = int(self.requestid)

            updated_values = {
                    'title': self._arg('request-title'),
                    'tags': ','.join(self.tag_list),
                    'reviewid': reviewid or None,
                    'repo': self._arg('request-repo'),
                    'branch': self._arg('request-branch'),
                    'comments': self._arg('request-comments'),
                    'description': self._arg('request-description'),
                    'watchers': watchers,
                    'modified': time.time(),
                    'revision': '0'*40,
            }

            if len(self._arg('request-takeover')):
                updated_values.update({'user': self.current_user})
                self.request_user = self.current_user
            else:
                self.request_user = self._arg('request-user')

            query = db.push_requests.update().where(
                    db.push_requests.c.id == self.requestid
                ).values(updated_values)
        else:
            query = db.push_requests.insert({
                'title': self._arg('request-title'),
                'user': self.current_user,
                'tags': ','.join(self.tag_list),
                'reviewid': self._arg('request-review') or None,
                'repo': self._arg('request-repo'),
                'branch': self._arg('request-branch'),
                'comments': self._arg('request-comments'),
                'description': self._arg('request-description'),
                'watchers': watchers,
                'created': time.time(),
                'modified': time.time(),
                'state': 'requested',
                'revision': '0'*40,
                })
            self.request_user = self.current_user

        db.execute_cb(query, self.on_request_upsert_complete)
Example #4
0
    def _api_PUSH(self):
        """Returns a JSON representation of a push."""
        push_id = util.get_int_arg(self.request, 'id')
        if not push_id:
            return self.send_error(404)

        query = db.push_pushes.select(db.push_pushes.c.id == push_id)
        db.execute_cb(query, self._on_PUSH_db_response)
Example #5
0
    def _api_REQUEST(self):
        """Returns a JSON representation of a push request."""
        request_id = util.get_int_arg(self.request, 'id')
        if not request_id:
            return self.send_error(404)

        query = db.push_requests.select(db.push_requests.c.id == request_id)
        db.execute_cb(query, self._on_REQUEST_db_response)
Example #6
0
    def on_request_upsert_complete(self, success, db_results):
        self.check_db_results(success, db_results)

        if not self.requestid:
            self.requestid = db_results.lastrowid

        query = db.push_checklist.select().where(db.push_checklist.c.request == self.requestid)
        db.execute_cb(query, self.on_existing_checklist_retrieved)
Example #7
0
    def post(self):
        if not self.current_user:
            return self.send_error(403)

        self.pushid = core.util.get_int_arg(self.request, 'push')
        self.request_ids = self.request.arguments.get('request', [])

        db.execute_cb(db.push_pushes.select().where(db.push_pushes.c.id == self.pushid), self.on_push_select)
Example #8
0
    def get_pushes(self):
        pushes = [None]
        def on_select_return(success, db_results):
            assert success
            pushes[0] = db_results.fetchall()

        db.execute_cb(db.push_pushes.select(), on_select_return)
        return pushes[0]
Example #9
0
    def get_requests(self):
        requests = [None]
        def on_select_return(success, db_results):
            assert success
            requests[0] = db_results.fetchall()

        db.execute_cb(db.push_requests.select(), on_select_return)
        return requests[0]
Example #10
0
    def _api_PUSHCONTENTS(self):
        """Returns a set of JSON representations of requests in a given push."""
        push_id = util.get_int_arg(self.request, "id")
        if not push_id:
            return self.send_error(404)

        query = db.push_requests.select(
            SA.and_(db.push_requests.c.id == db.push_pushcontents.c.request, db.push_pushcontents.c.push == push_id)
        )
        db.execute_cb(query, self._on_PUSHCONTENTS_db_response)
Example #11
0
    def post(self):
        if not self.current_user:
            return self.send_error(403)

        self.checklist = core.util.get_int_arg(self.request, 'id')
        new_value = core.util.get_int_arg(self.request, 'complete')

        query = db.push_checklist.update().where(
            db.push_checklist.c.id == self.checklist).values({'complete': new_value})
        db.execute_cb(query, lambda _, __:self.finish())
Example #12
0
    def get_push_for_request(self, requestid):
        pushid = [None]

        def on_select_return(success, db_results):
            assert success
            _, pushid[0] = db_results.fetchone()

        # check if we have a push in with request
        first_pushcontent_query = db.push_pushcontents.select(db.push_pushcontents.c.request == requestid)
        db.execute_cb(first_pushcontent_query, on_select_return)
        return pushid[0]
Example #13
0
    def _api_PUSHBYREQUEST(self):
        """Returns a JSON representation of a PUSH given a request id."""
        request_id = util.get_int_arg(self.request, 'id')
        if not request_id:
            return self.send_error(404)

        query = db.push_pushes.select(SA.and_(
            db.push_pushes.c.state != "discarded",
            db.push_pushcontents.c.push == db.push_pushes.c.id,
            db.push_pushcontents.c.request == request_id,
        ))
        db.execute_cb(query, self._on_PUSHBYREQUEST_db_response)
    def test_newrequest(self):
        results = []

        def on_db_return(success, db_results):
            assert success
            results.extend(db_results.fetchall())

        with nested(
            mock.patch.dict(db.Settings, T.MockedSettings),
            mock.patch.object(NewRequestServlet, "redirect"),
            mock.patch.object(
                NewRequestServlet,
                "get_current_user",
                return_value="testuser"
            )
        ):
            results = []
            db.execute_cb(db.push_requests.select(), on_db_return)
            num_results_before = len(results)

            request = {
                'request-title': 'Test Push Request Title',
                'request-tags': 'super-safe,logs',
                'request-review': 1,
                'request-repo': 'testuser',
                'request-branch': 'super_safe_fix',
                'request-comments': 'No comment',
                'request-description': 'I approve this fix!',
                'request-watchers': 'testuser2,testuser3',
            }

            response = self.fetch(
                "/newrequest",
                method="POST",
                body=urllib.urlencode(request)
            )
            T.assert_equal(response.error, None)

            results = []
            db.execute_cb(db.push_requests.select(), on_db_return)
            num_results_after = len(results)

            T.assert_equal(num_results_after, num_results_before + 1)

            last_req = self.get_requests()[-1]
            T.assert_equal(len(results), last_req['id'])
            T.assert_equal('testuser', last_req['user'])
            T.assert_equal(request['request-repo'], last_req['repo'])
            T.assert_equal(request['request-branch'], last_req['branch'])
            T.assert_equal(request['request-tags'], last_req['tags'])
            T.assert_equal(request['request-comments'], last_req['comments'])
            T.assert_equal(request['request-description'], last_req['description'])
            T.assert_equal(request['request-watchers'], last_req['watchers'])
    def get_checklists(self, requestid):
        checklists = [None]
        def on_select_return(success, db_results):
            assert success
            checklists[0] = db_results.fetchall()

        select_query = db.push_checklist.select().where(
                db.push_checklist.c.request == requestid)

        db.execute_cb(select_query, on_select_return)

        # id, *request*, *type*, complete, *target*
        simple_checklists = [(cl[1], cl[2], cl[4]) for cl in checklists[0]]
        return simple_checklists
Example #16
0
 def get(self):
     query = db.push_pushes.select(SA.and_(
                     db.push_pushes.c.state == 'accepting',
                     SA.exists([1],
                         SA.and_(
                             db.push_pushcontents.c.push == db.push_pushes.c.id,
                             db.push_pushcontents.c.request == db.push_requests.c.id,
                             db.push_requests.c.user == self.current_user,
                         ),
                     ),
                 ),
                 order_by=db.push_pushes.c.created.asc(),
             )
     db.execute_cb(query, self.on_db_response)
Example #17
0
 def post(self):
     if not self.current_user:
         return self.send_error(403)
     self.pushid = core.util.get_int_arg(self.request, 'id')
     query = db.push_pushes.update().where(db.push_pushes.c.id == self.pushid).values(**{
         'title': self._arg('push-title'),
         'user': self.current_user,
         'branch': self._arg('push-branch'),
         'revision': "0"*40,
         'modified': time.time(),
         })
     db.execute_cb(
         query,
         lambda _, __: self.redirect("/push?id=%d" % self.pushid)
     )
    def test_add_new_request(self):
        db.execute_cb(db.push_pushcontents.select(), self.record_pushcontents)
        num_results_before = len(self.results)

        request = { 'request': 2, 'push': 1 }
        response = self.fetch(
            '/addrequest',
            method='POST',
            body=urllib.urlencode(request)
        )
        T.assert_equal(response.error, None)

        db.execute_cb(db.push_pushcontents.select(), self.record_pushcontents)
        num_results_after = len(self.results)
        T.assert_equal(num_results_after, num_results_before + 1, "Add new request failed.")
Example #19
0
    def _api_PUSHITEMS(self):
        """Returns a JSON representation of a list of requests given a push id"""
        push_id = util.get_int_arg(self.request, 'push_id')
        if not push_id:
            return self.send_error(404)

        query = db.push_requests.select(
            SA.and_(
                db.push_requests.c.id == db.push_pushcontents.c.request,
                db.push_requests.c.state != 'pickme',
                db.push_pushcontents.c.push == push_id,
                ),
            order_by=(db.push_requests.c.user, db.push_requests.c.title),
        )
        db.execute_cb(query, self._on_PUSHITEMS_db_response)
    def test_newpush(self):
        pushes = []

        def on_db_return(success, db_results):
            assert success
            pushes.extend(db_results.fetchall())

        with nested(
            mock.patch.dict(db.Settings, T.MockedSettings),
            mock.patch.object(NewPushServlet, "get_current_user", return_value = "jblack"),
            mock.patch.object(NewPushServlet, "redirect"),
            mock.patch.object(MailQueue, "enqueue_user_email"),
        ):
            with mock.patch("%s.servlets.newpush.subprocess.call" % __name__) as mocked_call:
                title = "BestPushInTheWorld"
                branch = "jblack"
                push_type = "regular"

                uri = "/newpush?push-title=%s&branch=%s&push-type=%s" % (
                    title, branch, push_type
                )

                pushes = []
                db.execute_cb(db.push_pushes.select(), on_db_return)
                num_pushes_before = len(pushes)

                response = self.fetch(uri)
                assert response.error == None

                pushes = []
                db.execute_cb(db.push_pushes.select(), on_db_return)
                num_pushes_after = len(pushes)

                T.assert_equal(num_pushes_before + 1, num_pushes_after)

                # There should be one call to nodebot after a push is created
                T.assert_equal(servlets.newpush.subprocess.call.call_count, 1)

                # Verify that we have a valid call to
                # subprocess.call. Getting the arguments involves ugly
                # mock magic
                mocked_call.assert_called_once_with([
                    '/nail/sys/bin/nodebot',
                    '-i',
                    mock.ANY, # nickname
                    mock.ANY, # channel
                    mock.ANY, # msg
                ])
Example #21
0
    def test_newpush(self):
        pushes = []

        def on_db_return(success, db_results):
            assert success
            pushes.extend(db_results.fetchall())

        with nested(
            mock.patch.dict(db.Settings, T.MockedSettings),
            mock.patch.object(NewPushServlet, "get_current_user", return_value = "jblack"),
            mock.patch.object(NewPushServlet, "redirect"),
        ):
            with mock.patch("%s.servlets.newpush.subprocess.call" % __name__) as mocked_call:
                title = "BestPushInTheWorld"
                branch = "jblack"
                push_type = "regular"

                uri = "/newpush?push-title=%s&branch=%s&push-type=%s" % (
                    title, branch, push_type
                )

                pushes = []
                db.execute_cb(db.push_pushes.select(), on_db_return)
                num_pushes_before = len(pushes)

                response = self.fetch(uri)
                assert response.error == None

                pushes = []
                db.execute_cb(db.push_pushes.select(), on_db_return)
                num_pushes_after = len(pushes)

                T.assert_equal(num_pushes_before + 1, num_pushes_after)

                # There should be one call to nodebot after a push is created
                T.assert_equal(servlets.newpush.subprocess.call.call_count, 1)

                # Verify that we have a valid call to
                # subprocess.call. Getting the arguments involves ugly
                # mock magic
                call = mocked_call.call_args
                args = call[0][0]
                last_arg = args[-1]
                T.assert_in("regular push starting! https://", last_arg)
Example #22
0
    def get(self):
        if not self.current_user:
            return self.send_error(403)
        self.pushid = core.util.get_int_arg(self.request, 'id')
        self.pushmaster = core.util.get_int_arg(self.request, 'pushmaster')

        c = db.push_checklist.c
        r = db.push_requests.c

        query = SA.select([
                c.target, c.type, c.complete, c.id, c.request,
                r.title, r.repo, r.branch, r.user,
            ]).where(SA.and_(
                r.id == c.request,
                r.state != 'pickme',
                c.request == db.push_pushcontents.c.request,
                db.push_pushcontents.c.push == self.pushid,
            ))

        db.execute_cb(query, self.on_db_complete)
Example #23
0
    def test_process_queue_successful(self):
        """Update the request with its sha"""
        with nested(
            mock.patch("%s.core.git.GitQueue.update_request_failure" % __name__),
            mock.patch("%s.core.git.GitQueue.update_request_successful" % __name__),
            self.mocked_update_request(self.fake_request)
        ):
            # Successful call to update_request should trigger update_request_successful
            T.assert_equal(core.git.GitQueue.update_request_failure.call_count, 0)
            T.assert_equal(core.git.GitQueue.update_request_successful.call_count, 1)

        result = [None]
        def on_db_return(success, db_results):
            assert success, "Database error"
            result[0] = db_results.first()

        request_info_query = db.push_requests.select().where(
            db.push_requests.c.id == self.fake_request['id']
        )
        db.execute_cb(request_info_query, on_db_return)

        T.assert_equal(result[0][5], self.fake_request['revision'])
    def test_pickmerequest(self):
        push_contents = []

        def on_db_return(success, db_results):
            assert success
            push_contents.extend(db_results.fetchall())

        with self.fake_pickme_request():
            pushid = 1
            requestid = 2

            push_contents = []
            db.execute_cb(db.push_pushcontents.select(), on_db_return)
            num_contents_before = len(push_contents)

            uri = "/pickmerequest?push=%d&request=%d" % (pushid, requestid)
            response = self.fetch(uri)
            T.assert_equal(response.error, None)

            push_contents = []
            db.execute_cb(db.push_pushcontents.select(), on_db_return)
            num_contents_after = len(push_contents)

            T.assert_equal(num_contents_before + 1, num_contents_after)
    def test_checklist_toggle_post(self):
        complete = 0
        checklist_item = [None]

        def check_toggle(success, db_results):
            assert success
            checklist_item[0] = db_results.fetchone()
            T.assert_equal(checklist_item[0]['complete'], complete)

        with fake_checklist_request():
            # insert fake data from FakeDataMixin
            self.insert_requests()
            test_request1 = self.get_requests_by_user('testuser1')[0]
            # insert fake checklist data
            checklist_query = db.push_checklist.insert({
                'request': test_request1['id'],
                'type': 'search',
                'target': 'prod'
            })
            db.execute_cb(checklist_query, on_db_return)

            checklist_toggle_query = db.push_checklist.select(
                db.push_checklist.c.request == test_request1['id']
            )

            complete = 0
            db.execute_cb(checklist_toggle_query, check_toggle)

            complete = 1
            response = self.fetch(
                "/checklisttoggle",
                method="POST",
                body=urllib.urlencode({'id': checklist_item[0]['id'], 'complete': complete})
            )
            T.assert_equal(response.error, None)

            db.execute_cb(checklist_toggle_query, check_toggle)
Example #26
0
    def _api_REQUESTSEARCH(self):
        """Returns a list of requests matching a the specified filter(s)."""
        filters = []

        # Tag constraint
        for tag in self.request.arguments.get('tag', []):
            filters.append(db.push_requests.c.tags.op('regexp')('[[:<:]]' + tag + '[[:>:]]'))

        # Timestamp constraint
        mbefore = util.get_int_arg(self.request, 'mbefore')
        mafter = util.get_int_arg(self.request, 'mafter')
        if mbefore:
            filters.append(db.push_requests.c.modified < mbefore)
        if mafter:
            filters.append(db.push_requests.c.modified > mafter)

        cbefore = util.get_int_arg(self.request, 'cbefore')
        cafter = util.get_int_arg(self.request, 'cafter')
        if cbefore:
            filters.append(db.push_requests.c.created < cbefore)
        if cafter:
            filters.append(db.push_requests.c.created > cafter)

        # State constraint
        states = self.request.arguments.get('state', [])
        if states:
            filters.append(db.push_requests.c.state.in_(states))

        # User constraint
        users = self.request.arguments.get('user', [])
        if users:
            filters.append(db.push_requests.c.user.in_(users))

        # Repository constraint
        repos = self.request.arguments.get('repo', [])
        if repos:
            filters.append(db.push_requests.c.repo.in_(repos))

        # Branch constraint
        branches = self.request.arguments.get('branch', [])
        if branches:
            filters.append(db.push_requests.c.branch.in_(branches))

        # Revision constraint
        revisions = self.request.arguments.get('rev', [])
        if revisions:
            filters.append(db.push_requests.c.revision.in_(revisions))

        # Review constraint
        reviews = self.request.arguments.get('review', [])
        if reviews:
            filters.append(db.push_requests.c.reviewid.in_(reviews))

        # Title constraint
        for title in self.request.arguments.get('title', []):
            filters.append(db.push_requests.c.title.like('%' + title + '%'))

        # Only allow searches with at least one constraint (to avoid
        # accidental dumps of the entire table)
        if not filters:
            return self.send_error(409)

        query = db.push_requests.select(SA.and_(*filters))
        query = query.order_by(db.push_requests.c.id.desc())

        limit = util.get_int_arg(self.request, 'limit')
        if limit > 0:
            limit = max(min(1000, limit), 1)
            query = query.limit(limit)

        db.execute_cb(query, self._on_REQUESTSEARCH_db_response)
Example #27
0
 def _api_USERLIST(self):
     """Returns a JSON list of users who used PushManager for a request at least once."""
     query = db.push_requests.select(
         group_by=db.push_requests.c.user,
     )
     db.execute_cb(query, self._on_USERLIST_db_response)
 def test_convert_cleanup_type(self):
     rename_checklist_type.convert_checklist('search', 'not_search')
     cb = partial(self.verify_type_rename, 'search', 'not_search')
     db.execute_cb(db.push_checklist.select(), cb)
 def test_convert_notype(self):
     rename_checklist_type.convert_checklist('nonexistent', 'random')
     cb = partial(self.verify_database_state, self.checklist_data)
     db.execute_cb(db.push_checklist.select(), cb)
Example #30
0
 def insert_pushcontent(self, requestid, pushid):
     db.execute_cb(
         db.push_pushcontents.insert({'request': requestid, 'push': pushid}),
         self.on_db_return
     )