コード例 #1
0
 def test_create_public_project_as_user_clone_as_user(self):
     """ Create public project as user then clone as user
     """
     pname = 'p_%s' % create_random_str()
     # create the project as admin
     self.create_project(pname, config.USER_2)
     # add user2 ssh pubkey to user2
     gu = GerritUtils(
         config.GATEWAY_URL,
         auth_cookie=config.USERS[config.USER_2]['auth_cookie'])
     gu.add_pubkey(config.USER_2_PUB_KEY)
     # prepare to clone
     priv_key_path = set_private_key(config.USER_2_PRIV_KEY)
     self.dirs_to_delete.append(os.path.dirname(priv_key_path))
     ggu = GerritGitUtils(config.USER_2,
                          priv_key_path,
                          config.USERS[config.USER_2]['email'])
     url = "ssh://%s@%s:29418/%s" % (config.USER_2,
                                     config.GATEWAY_HOST, pname)
     # clone
     clone_dir = ggu.clone(url, pname)
     self.dirs_to_delete.append(os.path.dirname(clone_dir))
     # Test that the clone is a success
     self.assertTrue(os.path.isdir(clone_dir))
     # Verify master own the .gitreview file
     self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                 '.gitreview')))
コード例 #2
0
 def test_create_public_project_as_user_clone_as_user(self):
     """ Create public project as user then clone as user
     """
     pname = 'p_%s' % create_random_str()
     # create the project as admin
     self.create_project(pname, config.USER_2)
     # add user2 ssh pubkey to user2
     gu = GerritUtils(
         'https://%s/' % config.GATEWAY_HOST,
         auth_cookie=config.USERS[config.USER_2]['auth_cookie'])
     gu.add_pubkey(config.USER_2_PUB_KEY)
     # prepare to clone
     priv_key_path = set_private_key(config.USER_2_PRIV_KEY)
     self.dirs_to_delete.append(os.path.dirname(priv_key_path))
     ggu = GerritGitUtils(config.USER_2,
                          priv_key_path,
                          config.USERS[config.USER_2]['email'])
     url = "ssh://%s@%s:29418/%s" % (config.USER_2,
                                     config.GATEWAY_HOST, pname)
     # clone
     clone_dir = ggu.clone(url, pname)
     self.dirs_to_delete.append(os.path.dirname(clone_dir))
     # Test that the clone is a success
     self.assertTrue(os.path.isdir(clone_dir))
     # Verify master own the .gitreview file
     self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                 '.gitreview')))
コード例 #3
0
    def _prepare_review_submit_testing(self, data=None):
        pname = 'p_%s' % create_random_str()
        self.create_project(pname)
        gu = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
        k_index = gu.add_pubkey(config.USERS[config.ADMIN_USER]["pubkey"])
        self.assertTrue(gu.project_exists(pname))
        priv_key_path = set_private_key(
            config.USERS[config.ADMIN_USER]["privkey"])
        gitu = GerritGitUtils(config.ADMIN_USER, priv_key_path,
                              config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER, config.GATEWAY_HOST,
                                        pname)
        clone_dir = gitu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))

        if not data:
            gitu.add_commit_and_publish(clone_dir, "master", "Test commit")
        else:
            file(os.path.join(clone_dir, "file"), 'w').write(data[1])
            gitu.add_commit_and_publish(clone_dir,
                                        "master",
                                        "Test commit",
                                        fnames=[data[0]])

        change_ids = gu.get_my_changes_for_project(pname)
        self.assertEqual(len(change_ids), 1)
        change_id = change_ids[0]

        return change_id, gu, k_index, pname
コード例 #4
0
    def test_review_labels(self):
        """ Test if list of review labels are as expected
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname)
        un = config.ADMIN_USER
        gu = GerritUtils(config.GATEWAY_URL,
                         auth_cookie=config.USERS[un]['auth_cookie'])
        k_index = gu.add_pubkey(config.USERS[un]["pubkey"])
        self.assertTrue(gu.project_exists(pname))
        priv_key_path = set_private_key(config.USERS[un]["privkey"])
        gitu = GerritGitUtils(un, priv_key_path, config.USERS[un]['email'])
        url = "ssh://%s@%s:29418/%s" % (un, config.GATEWAY_HOST, pname)
        clone_dir = gitu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))

        gitu.add_commit_and_publish(clone_dir, "master", "Test commit")

        change_ids = gu.get_my_changes_for_project(pname)
        self.assertEqual(len(change_ids), 1)
        change_id = change_ids[0]

        labels = gu.get_labels_list_for_change(change_id)

        self.assertIn('Workflow', labels)
        self.assertIn('Code-Review', labels)
        self.assertIn('Verified', labels)
        self.assertEqual(len(labels.keys()), 3)

        gu.del_pubkey(k_index)
コード例 #5
0
    def _prepare_review_submit_testing(self, project_options=None):
        if project_options is None:
            u2mail = config.USERS[config.USER_2]['email']
            project_options = {'core-group': u2mail}
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, project_options)
        un = config.ADMIN_USER
        gu = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[un]['auth_cookie'])
        k_index = gu.add_pubkey(config.USERS[un]["pubkey"])
        self.assertTrue(gu.project_exists(pname))
        priv_key_path = set_private_key(config.USERS[un]["privkey"])
        gitu = GerritGitUtils(un,
                              priv_key_path,
                              config.USERS[un]['email'])
        url = "ssh://%s@%s:29418/%s" % (un, config.GATEWAY_HOST,
                                        pname)
        clone_dir = gitu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))

        gitu.add_commit_and_publish(clone_dir, "master", "Test commit")

        change_ids = gu.get_my_changes_for_project(pname)
        self.assertEqual(len(change_ids), 1)
        change_id = change_ids[0]

        return change_id, gu, k_index
コード例 #6
0
    def test_review_labels(self):
        """ Test if list of review labels are as expected
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname)
        un = config.ADMIN_USER
        gu = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[un]['auth_cookie'])
        k_index = gu.add_pubkey(config.USERS[un]["pubkey"])
        self.assertTrue(gu.project_exists(pname))
        priv_key_path = set_private_key(config.USERS[un]["privkey"])
        gitu = GerritGitUtils(un,
                              priv_key_path,
                              config.USERS[un]['email'])
        url = "ssh://%s@%s:29418/%s" % (un, config.GATEWAY_HOST,
                                        pname)
        clone_dir = gitu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))

        gitu.add_commit_and_publish(clone_dir, "master", "Test commit")

        change_ids = gu.get_my_changes_for_project(pname)
        self.assertEqual(len(change_ids), 1)
        change_id = change_ids[0]

        labels = gu.get_labels_list_for_change(change_id)

        self.assertIn('Workflow', labels)
        self.assertIn('Code-Review', labels)
        self.assertIn('Verified', labels)
        self.assertEqual(len(labels.keys()), 3)

        gu.del_pubkey(k_index)
コード例 #7
0
    def test_check_add_automatic_reviewers(self):
        """ Test if reviewers-by-blame plugin works
        """
        data = "this\nis\na\ncouple\nof\nlines"
        change_id, gu, k1_index, pname = self._prepare_review_submit_testing(
            ('file', data))

        # Merge the change
        gu.submit_change_note(change_id, "current", "Code-Review", "2")
        gu.submit_change_note(change_id, "current", "Verified", "2")
        gu.submit_change_note(change_id, "current", "Workflow", "1")
        self.assertTrue(gu.submit_patch(change_id, "current"))

        gu2 = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[config.USER_2]['auth_cookie'])
        # Change the file we have commited with Admin user
        k2_index = gu2.add_pubkey(config.USERS[config.USER_2]["pubkey"])
        priv_key_path = set_private_key(config.USERS[config.USER_2]["privkey"])
        gitu2 = GerritGitUtils(config.USER_2, priv_key_path,
                               config.USERS[config.USER_2]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.USER_2, config.GATEWAY_HOST,
                                        pname)
        clone_dir = gitu2.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))
        data = ['this', 'is', 'some', 'lines']
        file(os.path.join(clone_dir, "file"), 'w').write("\n".join(data))
        gitu2.add_commit_and_publish(clone_dir,
                                     "master",
                                     "Test commit",
                                     fnames=["file"])
        # Get the change id
        change_ids = gu2.get_my_changes_for_project(pname)
        self.assertEqual(len(change_ids), 1)
        change_id = change_ids[0]
        # Verify first_u has been automatically added to reviewers
        for retry in xrange(3):
            if len(gu2.get_reviewers(change_id)) > 0:
                break
            time.sleep(1)
        reviewers = gu2.get_reviewers(change_id)
        self.assertEqual(len(reviewers), 1)
        self.assertEqual(reviewers[0], config.ADMIN_USER)

        gu.del_pubkey(k1_index)
        gu2.del_pubkey(k2_index)
コード例 #8
0
    def test_check_download_commands(self):
        """ Test if download commands plugin works
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname)
        un = config.ADMIN_USER
        gu = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[un]['auth_cookie'])
        self.assertTrue(gu.project_exists(pname))
        k_index = gu.add_pubkey(config.USERS[un]["pubkey"])
        priv_key_path = set_private_key(config.USERS[un]["privkey"])
        gitu = GerritGitUtils(un,
                              priv_key_path,
                              config.USERS[un]['email'])
        url = "ssh://%s@%s:29418/%s" % (un, config.GATEWAY_HOST,
                                        pname)
        clone_dir = gitu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))

        gitu.add_commit_and_publish(clone_dir, "master", "Test commit")

        change_ids = gu.get_my_changes_for_project(pname)
        self.assertEqual(len(change_ids), 1)
        change_id = change_ids[0]
        resp = gu.get_change_last_patchset(change_id)
        self.assertIn("current_revision", resp)
        self.assertIn("revisions", resp)
        current_rev = resp["current_revision"]
        fetch = resp["revisions"][current_rev]["fetch"]
        self.assertGreater(fetch.keys(), 0)

        # disable and check if the fetch has anything
        gu.e_d_plugin("download-commands", 'disable')
        resp = gu.get_change_last_patchset(change_id)
        fetch = resp["revisions"][current_rev]["fetch"]
        self.assertEqual(len(fetch.keys()), 0)

        # enable the plugin and check if the fetch information is valid
        gu.e_d_plugin("download-commands", 'enable')
        resp = gu.get_change_last_patchset(change_id)
        fetch = resp["revisions"][current_rev]["fetch"]
        self.assertGreater(len(fetch.keys()), 0)

        gu.del_pubkey(k_index)
コード例 #9
0
    def test_check_download_commands(self):
        """ Test if download commands plugin works
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname)
        un = config.ADMIN_USER
        gu = GerritUtils(config.GATEWAY_URL,
                         auth_cookie=config.USERS[un]['auth_cookie'])
        self.assertTrue(gu.project_exists(pname))
        k_index = gu.add_pubkey(config.USERS[un]["pubkey"])
        priv_key_path = set_private_key(config.USERS[un]["privkey"])
        gitu = GerritGitUtils(un, priv_key_path, config.USERS[un]['email'])
        url = "ssh://%s@%s:29418/%s" % (un, config.GATEWAY_HOST, pname)
        clone_dir = gitu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))

        gitu.add_commit_and_publish(clone_dir, "master", "Test commit")

        change_ids = gu.get_my_changes_for_project(pname)
        self.assertEqual(len(change_ids), 1)
        change_id = change_ids[0]
        resp = gu.get_change_last_patchset(change_id)
        self.assertIn("current_revision", resp)
        self.assertIn("revisions", resp)
        current_rev = resp["current_revision"]
        fetch = resp["revisions"][current_rev]["fetch"]
        self.assertGreater(fetch.keys(), 0)

        # disable and check if the fetch has anything
        gu.e_d_plugin("download-commands", 'disable')
        resp = gu.get_change_last_patchset(change_id)
        fetch = resp["revisions"][current_rev]["fetch"]
        self.assertEqual(len(fetch.keys()), 0)

        # enable the plugin and check if the fetch information is valid
        gu.e_d_plugin("download-commands", 'enable')
        resp = gu.get_change_last_patchset(change_id)
        fetch = resp["revisions"][current_rev]["fetch"]
        self.assertGreater(len(fetch.keys()), 0)

        gu.del_pubkey(k_index)
コード例 #10
0
    def _prepare_review_submit_testing(self, project_options=None):
        if project_options is None:
            u2mail = config.USERS[config.USER_2]['email']
            project_options = {'core-group': u2mail}
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, project_options)
        un = config.ADMIN_USER
        gu = GerritUtils(config.GATEWAY_URL,
                         auth_cookie=config.USERS[un]['auth_cookie'])
        k_index = gu.add_pubkey(config.USERS[un]["pubkey"])
        self.assertTrue(gu.project_exists(pname))
        priv_key_path = set_private_key(config.USERS[un]["privkey"])
        gitu = GerritGitUtils(un, priv_key_path, config.USERS[un]['email'])
        url = "ssh://%s@%s:29418/%s" % (un, config.GATEWAY_HOST, pname)
        clone_dir = gitu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))

        gitu.add_commit_and_publish(clone_dir, "master", "Test commit")

        change_ids = gu.get_my_changes_for_project(pname)
        self.assertEqual(len(change_ids), 1)
        change_id = change_ids[0]

        return change_id, gu, k_index
コード例 #11
0
    def test_check_add_automatic_reviewers(self):
        """ Test if reviewers-by-blame plugin works
        """
        pname = 'p_%s' % create_random_str()
        u2mail = config.USERS[config.USER_2]['email']
        options = {'core-group': u2mail}
        self.create_project(pname, options)
        first_u = config.ADMIN_USER
        gu_first_u = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[first_u]['auth_cookie'])
        self.assertTrue(gu_first_u.project_exists(pname))
        # Push data in the create project as Admin user
        k1_index = gu_first_u.add_pubkey(config.USERS[first_u]["pubkey"])
        priv_key_path = set_private_key(config.USERS[first_u]["privkey"])
        gitu = GerritGitUtils(first_u,
                              priv_key_path,
                              config.USERS[first_u]['email'])
        url = "ssh://%s@%s:29418/%s" % (first_u, config.GATEWAY_HOST,
                                        pname)
        clone_dir = gitu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))
        data = ['this', 'is', 'a', 'couple', 'of', 'lines']
        clone_dir = gitu.clone(url, pname)
        file(os.path.join(clone_dir, "file"), 'w').write("\n".join(data))
        gitu.add_commit_and_publish(clone_dir, "master", "Test commit",
                                    fnames=["file"])
        # Get the change id
        change_ids = gu_first_u.get_my_changes_for_project(pname)
        self.assertEqual(len(change_ids), 1)
        change_id = change_ids[0]
        # Merge the change
        gu_first_u.submit_change_note(change_id, "current", "Code-Review", "2")
        gu_first_u.submit_change_note(change_id, "current", "Verified", "2")
        gu_first_u.submit_change_note(change_id, "current", "Workflow", "1")
        second_u = config.USER_2
        gu_second_u = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[second_u]['auth_cookie'])
        self.assertTrue(gu_first_u.submit_patch(change_id, "current"))
        # Change the file we have commited with Admin user
        k2_index = gu_second_u.add_pubkey(config.USERS[second_u]["pubkey"])
        priv_key_path = set_private_key(config.USERS[second_u]["privkey"])
        gitu = GerritGitUtils(second_u,
                              priv_key_path,
                              config.USERS[second_u]['email'])
        url = "ssh://%s@%s:29418/%s" % (second_u, config.GATEWAY_HOST,
                                        pname)
        clone_dir = gitu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))
        data = ['this', 'is', 'some', 'lines']
        file(os.path.join(clone_dir, "file"), 'w').write("\n".join(data))
        gitu.add_commit_and_publish(clone_dir, "master", "Test commit",
                                    fnames=["file"])
        # Get the change id
        change_ids = gu_second_u.get_my_changes_for_project(pname)
        self.assertEqual(len(change_ids), 1)
        change_id = change_ids[0]
        # Verify first_u has been automatically added to reviewers
        attempts = 0
        while True:
            if len(gu_second_u.get_reviewers(change_id)) > 0 or attempts >= 3:
                break
            attempts += 1
            time.sleep(1)
        reviewers = gu_second_u.get_reviewers(change_id)
        self.assertGreaterEqual(len(reviewers), 1)
        self.assertTrue(first_u in reviewers)

        gu_first_u.del_pubkey(k1_index)
        gu_second_u.del_pubkey(k2_index)
コード例 #12
0
class TestProjectTestsWorkflow(Base):
    """ Functional tests to verify the configuration of a project test
    """
    @classmethod
    def setUpClass(cls):
        cls.msu = ManageSfUtils(config.GATEWAY_URL)
        cls.sample_project_dir = \
            os.path.join(config.SF_TESTS_DIR, "sample_project/")

    @classmethod
    def tearDownClass(cls):
        pass

    def setUp(self):
        self.projects = []
        self.dirs_to_delete = []
        self.un = config.ADMIN_USER
        self.gu = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[self.un]['auth_cookie'])
        self.gu2 = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[config.USER_2]['auth_cookie'])
        self.ju = JenkinsUtils()
        self.gu.add_pubkey(config.USERS[self.un]["pubkey"])
        priv_key_path = set_private_key(config.USERS[self.un]["privkey"])
        self.gitu_admin = GerritGitUtils(self.un,
                                         priv_key_path,
                                         config.USERS[self.un]['email'])
        # Clone the config repo and make change to it
        # in order to test the new sample_project
        self.config_clone_dir = self.clone_as_admin("config")
        self.original_layout = file(os.path.join(
            self.config_clone_dir, "zuul/layout.yaml")).read()
        self.original_zuul_projects = file(os.path.join(
            self.config_clone_dir, "zuul/projects.yaml")).read()
        self.original_project = file(os.path.join(
            self.config_clone_dir, "jobs/projects.yaml")).read()
        # Put USER_2 as core for config project
        self.gu.add_group_member(config.USER_2, "config-core")

    def tearDown(self):
        self.restore_config_repo(self.original_layout,
                                 self.original_project,
                                 self.original_zuul_projects)
        for name in self.projects:
            self.msu.deleteProject(name,
                                   config.ADMIN_USER)
        for dirs in self.dirs_to_delete:
            shutil.rmtree(dirs)

    def assert_reviewer_approvals(self, change_id, value):
        approvals = {}
        for _ in range(90):
            approvals = self.gu.get_reviewer_approvals(change_id,
                                                       'jenkins')
            if approvals and approvals.get('Verified') == value:
                break
            time.sleep(1)
        self.assertEqual(value, approvals.get('Verified'))

    def clone_as_admin(self, pname):
        url = "ssh://%s@%s:29418/%s" % (self.un, config.GATEWAY_HOST,
                                        pname)
        clone_dir = self.gitu_admin.clone(url, pname)
        if os.path.dirname(clone_dir) not in self.dirs_to_delete:
            self.dirs_to_delete.append(os.path.dirname(clone_dir))
        return clone_dir

    def restore_config_repo(self, layout, project, zuul):
        file(os.path.join(
            self.config_clone_dir, "zuul/layout.yaml"), 'w').write(
            layout)
        file(os.path.join(
            self.config_clone_dir, "zuul/projects.yaml"), 'w').write(
            zuul)
        file(os.path.join(
            self.config_clone_dir, "jobs/projects.yaml"), 'w').write(
            project)
        self.commit_direct_push_as_admin(
            self.config_clone_dir,
            "Restore layout.yaml and projects.yaml")

    def commit_direct_push_as_admin(self, clone_dir, msg):
        # Stage, commit and direct push the additions on master
        self.gitu_admin.add_commit_for_all_new_additions(clone_dir, msg)
        self.gitu_admin.direct_push_branch(clone_dir, 'master')

    def push_review_as_admin(self, clone_dir, msg):
        # Stage, commit and direct push the additions on master
        self.gitu_admin.add_commit_for_all_new_additions(clone_dir, msg)
        self.gitu_admin.review_push_branch(clone_dir, 'master')

    def create_project(self, name, user,
                       options=None):
        self.msu.createProject(name, user,
                               options)
        self.projects.append(name)

    def test_check_project_test_workflow(self):
        """ Validate new project to test via zuul layout.yaml
        """
        # We want to create a project, provide project source
        # code with tests. We then configure zuul/jjb to handle the
        # run of the test cases. We then validate Gerrit has been
        # updated about the test results
        # We use the sample-project (that already exists)

        pname = 'test_workflow_%s' % create_random_str()
        # Be sure the project does not exist
        self.msu.deleteProject(pname,
                               config.ADMIN_USER)
        # Create it
        self.create_project(pname, config.ADMIN_USER)

        # Add the sample-project to the empty repository
        clone_dir = self.clone_as_admin(pname)
        copytree(self.sample_project_dir, clone_dir)
        self.commit_direct_push_as_admin(clone_dir, "Add the sample project")

        # Change to config/zuul/layout.yaml and jobs/projects.yaml
        # in order to test the new project
        ycontent = file(os.path.join(
            self.config_clone_dir, "zuul/projects.yaml")).read()
        file(os.path.join(
            self.config_clone_dir, "zuul/projects.yaml"), 'w').write(
            ycontent.replace("zuul-demo", pname),
        )
        ycontent2 = load(file(os.path.join(
            self.config_clone_dir, "jobs/projects.yaml")).read())
        sp2 = copy.deepcopy(
            [p for p in ycontent2 if 'project' in p and
                p['project']['name'] == 'zuul-demo'][0])
        sp2['project']['name'] = pname
        ycontent2.append(sp2)
        file(os.path.join(
            self.config_clone_dir, "jobs/projects.yaml"), 'w').write(
            dump(ycontent2))

        # Retrieve the previous build number for config-check
        last_success_build_num_ch = \
            self.ju.get_last_build_number("config-check",
                                          "lastSuccessfulBuild")
        # Retrieve the previous build number for config-update
        last_success_build_num_cu = \
            self.ju.get_last_build_number("config-update",
                                          "lastSuccessfulBuild")

        # Send review (config-check) will be triggered
        self.push_review_as_admin(
            self.config_clone_dir,
            "Add config definition in Zuul/JJB config for %s" % pname)

        # Wait for config-check to finish and verify the success
        self.ju.wait_till_job_completes("config-check",
                                        last_success_build_num_ch,
                                        "lastSuccessfulBuild")

        last_build_num_ch, last_success_build_num_ch = 0, 1
        attempt = 0
        while last_build_num_ch != last_success_build_num_ch:
            if attempt >= 90:
                break
            time.sleep(1)
            last_build_num_ch = \
                self.ju.get_last_build_number("config-check",
                                              "lastBuild")
            last_success_build_num_ch = \
                self.ju.get_last_build_number("config-check",
                                              "lastSuccessfulBuild")
            attempt += 1

        self.assertEqual(last_build_num_ch, last_success_build_num_ch)
        # let some time to Zuul to update the test result to Gerrit.
        time.sleep(2)

        # Get the change id
        change_ids = self.gu.get_my_changes_for_project("config")
        self.assertGreater(len(change_ids), 0)
        change_id = change_ids[0]

        # Check whether zuul sets verified to +1 after running the tests
        # let some time to Zuul to update the test result to Gerrit.
        self.assert_reviewer_approvals(change_id, '+1')

        # review the change
        self.gu2.submit_change_note(change_id, "current", "Code-Review", "2")
        self.gu2.submit_change_note(change_id, "current", "Workflow", "1")

        # now zuul processes gate pipeline and runs config-check job
        # Wait for config-check to finish and verify the success
        self.ju.wait_till_job_completes("config-check",
                                        last_success_build_num_ch,
                                        "lastSuccessfulBuild")

        last_build_num_ch, last_success_build_num_ch = 0, 1
        attempt = 0
        while last_build_num_ch != last_success_build_num_ch:
            if attempt >= 90:
                break
            time.sleep(1)
            last_build_num_ch = \
                self.ju.get_last_build_number("config-check",
                                              "lastBuild")
            last_success_build_num_ch = \
                self.ju.get_last_build_number("config-check",
                                              "lastSuccessfulBuild")
            attempt += 1

        self.assertEqual(last_build_num_ch, last_success_build_num_ch)

        # Check whether zuul sets verified to +2 after running the tests
        # let some time to Zuul to update the test result to Gerrit.
        self.assert_reviewer_approvals(change_id, '+2')

        # verify whether zuul merged the patch
        change = self.gu.get_change('config', 'master', change_id)
        change_status = change['status']
        attempt = 0
        while change_status != 'MERGED':
            if attempt >= 90:
                break
            time.sleep(1)
            change = self.gu.get_change('config', 'master', change_id)
            change_status = change['status']
            attempt += 1
        self.assertEqual(change_status, 'MERGED')

        # Test post pipe line
        # as the patch is merged, post pieline should run config-update job
        # Wait for config-update to finish and verify the success
        self.ju.wait_till_job_completes("config-update",
                                        last_success_build_num_cu,
                                        "lastSuccessfulBuild")
        last_build_num_cu = \
            self.ju.get_last_build_number("config-update",
                                          "lastBuild")
        last_success_build_num_cu = \
            self.ju.get_last_build_number("config-update",
                                          "lastSuccessfulBuild")
        self.assertEqual(last_build_num_cu, last_success_build_num_cu)

        # Retrieve the prev build number for pname-unit-tests
        # Retrieve the prev build number for pname-functional-tests
        last_success_build_num_sp_ut = \
            self.ju.get_last_build_number("%s-unit-tests" % pname,
                                          "lastSuccessfulBuild")
        last_success_build_num_sp_ft = \
            self.ju.get_last_build_number("%s-functional-tests" % pname,
                                          "lastSuccessfulBuild")
        # Test config-update
        # config-update should have created jobs for pname
        # Trigger tests on pname
        # Send a review and check tests has been run
        self.gitu_admin.add_commit_and_publish(
            clone_dir, 'master', "Add useless file",
            self.un)
        # Wait for pname-unit-tests to finish and verify the success
        self.ju.wait_till_job_completes("%s-unit-tests" % pname,
                                        last_success_build_num_sp_ut,
                                        "lastSuccessfulBuild")
        # Wait for pname-functional-tests to end and check the success
        self.ju.wait_till_job_completes("%s-functional-tests" % pname,
                                        last_success_build_num_sp_ft,
                                        "lastSuccessfulBuild")
        # Check the unit tests succeed
        last_build_num_sp_ut = \
            self.ju.get_last_build_number("%s-unit-tests" % pname,
                                          "lastBuild")
        last_success_build_num_sp_ut = \
            self.ju.get_last_build_number("%s-unit-tests" % pname,
                                          "lastSuccessfulBuild")
        self.assertEqual(last_build_num_sp_ut, last_success_build_num_sp_ut)
        # Check the functional tests succeed
        last_build_num_sp_ft = \
            self.ju.get_last_build_number("%s-functional-tests" % pname,
                                          "lastBuild")
        last_success_build_num_sp_ft = \
            self.ju.get_last_build_number("%s-functional-tests" % pname,
                                          "lastSuccessfulBuild")
        self.assertEqual(last_build_num_sp_ft, last_success_build_num_sp_ft)

        # Get the change id
        change_ids = self.gu.get_my_changes_for_project(pname)
        self.assertGreater(len(change_ids), 0)
        change_id = change_ids[0]

        # let some time to Zuul to update the test result to Gerrit.
        for i in range(90):
            if "jenkins" in self.gu.get_reviewers(change_id):
                break
            time.sleep(1)

        self.assert_reviewer_approvals(change_id, '+1')
コード例 #13
0
    def test_check_zuul_operations(self):
        """ Test if zuul verifies project correctly through zuul-demo project
        """
        # zuul-demo - test project used exclusively to test zuul installation
        # The necessary project descriptions are already declared in Jenkins
        # and zuul

        pname = 'demo/zuul-demo'

        self.create_project(pname, config.ADMIN_USER)
        un = config.ADMIN_USER
        gu = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[un]['auth_cookie'])
        ju = JenkinsUtils()
        k_index = gu.add_pubkey(config.USERS[un]["pubkey"])
        # Gerrit part
        self.assertTrue(gu.project_exists(pname))
        priv_key_path = set_private_key(config.USERS[un]["privkey"])
        gitu = GerritGitUtils(un,
                              priv_key_path,
                              config.USERS[un]['email'])
        url = "ssh://%s@%s:29418/%s" % (un, config.GATEWAY_HOST,
                                        pname)
        clone_dir = gitu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))

        last_fail_build_num_ft = \
            ju.get_last_build_number("zuul-demo-functional-tests",
                                     "lastFailedBuild")
        last_fail_build_num_ut = \
            ju.get_last_build_number("zuul-demo-unit-tests",
                                     "lastFailedBuild")
        last_succeed_build_num_ft = \
            ju.get_last_build_number("zuul-demo-functional-tests",
                                     "lastSuccessfulBuild")
        last_succeed_build_num_ut = \
            ju.get_last_build_number("zuul-demo-unit-tests",
                                     "lastSuccessfulBuild")

        gitu.add_commit_and_publish(clone_dir, "master", "Test commit")

        change_ids = gu.get_my_changes_for_project(pname)
        self.assertGreater(len(change_ids), 0)
        change_id = change_ids[0]

        # Give some time for jenkins to work
        ju.wait_till_job_completes("zuul-demo-functional-tests",
                                   last_fail_build_num_ft, "lastFailedBuild")
        ju.wait_till_job_completes("zuul-demo-unit-tests",
                                   last_fail_build_num_ut, "lastFailedBuild")

        attempt = 0
        while "jenkins" not in gu.get_reviewers(change_id):
            if attempt >= 90:
                break
            time.sleep(1)
            attempt += 1

        attempt = 0
        while gu.get_reviewer_approvals(change_id, 'jenkins')['Verified'] \
                != '-1':
            if attempt >= 90:
                break
            time.sleep(1)
            attempt += 1

        self.assertEqual(
            gu.get_reviewer_approvals(change_id, 'jenkins')['Verified'], '-1')

        # Add the test case files and resubmit for review
        data = "echo Working"
        files = ["run_functional-tests.sh", "run_tests.sh"]

        for f in files:
            file(os.path.join(clone_dir, f), 'w').write(data)
            os.chmod(os.path.join(clone_dir, f), 0755)

        gitu.add_commit_and_publish(clone_dir, "master", None, fnames=files)

        # Give some time for jenkins to work
        ju.wait_till_job_completes("zuul-demo-functional-tests",
                                   last_succeed_build_num_ft,
                                   "lastSuccessfulBuild")
        ju.wait_till_job_completes("zuul-demo-unit-tests",
                                   last_succeed_build_num_ut,
                                   "lastSuccessfulBuild")

        attempt = 0
        while "jenkins" not in gu.get_reviewers(change_id):
            if attempt >= 90:
                break
            time.sleep(1)
            attempt += 1

        attempt = 0
        while gu.get_reviewer_approvals(change_id, 'jenkins')['Verified'] \
                != '+1':
            if attempt >= 90:
                break
            time.sleep(1)
            attempt += 1

        self.assertEqual(
            gu.get_reviewer_approvals(change_id, 'jenkins')['Verified'], '+1')

        gu.del_pubkey(k_index)
コード例 #14
0
class TestProjectReplication(Base):
    """ Functional tests to verify the gerrit replication feature
    """
    def setUp(self):
        self.msu = ManageSfUtils(config.GATEWAY_URL)
        self.un = config.ADMIN_USER
        self.gu = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[self.un]['auth_cookie'])
        self.gu2 = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[config.USER_2]['auth_cookie'])
        self.k_idx = self.gu2.add_pubkey(config.USERS[config.USER_2]["pubkey"])
        priv_key_path = set_private_key(config.USERS[self.un]["privkey"])
        self.gitu_admin = GerritGitUtils(self.un,
                                         priv_key_path,
                                         config.USERS[self.un]['email'])
        # Configuration to access mirror repo present in mysql
        self.msql_repo_path = "ssh://%s@%s/%s" \
                              % (config.GERRIT_USER, config.GATEWAY_HOST,
                                 'home/gerrit/site_path/git/')
        # prepare environment for git clone on mirror repo
        self.mt = Tool()
        self.mt_tempdir = tempfile.mkdtemp()
        priv_key = file(config.GERRIT_SERVICE_PRIV_KEY_PATH, 'r').read()
        priv_key_path = os.path.join(self.mt_tempdir, 'user.priv')
        file(priv_key_path, 'w').write(priv_key)
        os.chmod(priv_key_path, stat.S_IREAD | stat.S_IWRITE)
        ssh_wrapper = "ssh -o StrictHostKeyChecking=no -i " \
                      "%s \"$@\"" % priv_key_path
        wrapper_path = os.path.join(self.mt_tempdir, 'ssh_wrapper.sh')
        file(wrapper_path, 'w').write(ssh_wrapper)
        os.chmod(wrapper_path, stat.S_IRWXU)
        self.mt.env['GIT_SSH'] = wrapper_path
        self.pname = 'test-replication'

    def tearDown(self):
        self.deleteConfigSection(self.un, self.pname)
        self.deleteMirrorRepo(self.pname)
        self.msu.deleteProject(self.pname, self.un)
        self.gu2.del_pubkey(self.k_idx)

    # Can't use GerritGitUtils.clone as not sure when source uri repo in mysql
    # be ready.(i.e gerrit is taking time to create the mirror repo in mysql
    # node) So this clone may succeed or fail, we don't need 'git review -s'
    # and other review commands in clone method
    def clone(self, uri, target):
        self.assertTrue(uri.startswith('ssh://'))
        cmd = "git clone %s %s" % (uri, target)
        self.mt.exe(cmd, self.mt_tempdir)
        clone = os.path.join(self.mt_tempdir, target)
        return clone

    def create_project(self, name, user, options=None):
        self.msu.createProject(name, user, options)

    def ssh_run_cmd(self, sshkey_priv_path, user, host, subcmd):
        host = '%s@%s' % (user, host)
        sshcmd = ['ssh', '-o', 'LogLevel=ERROR',
                  '-o', 'StrictHostKeyChecking=no',
                  '-o', 'UserKnownHostsFile=/dev/null', '-i',
                  sshkey_priv_path, host]
        cmd = sshcmd + subcmd

        p = Popen(cmd, stdout=PIPE)
        return p.communicate()

    def deleteMirrorRepo(self, name):
        sshkey_priv_path = config.GERRIT_SERVICE_PRIV_KEY_PATH
        user = '******'
        host = config.GATEWAY_HOST
        mirror_path = '/home/gerrit/site_path/git/%s.git' % name
        cmd = ['rm', '-rf', mirror_path]
        self.ssh_run_cmd(sshkey_priv_path, user, host, cmd)

    def createConfigSection(self, user, project):
        # Section name will be node name and the project
        section = 'mysql_%s' % project
        host = '%s@%s' % (config.GERRIT_USER, config.GATEWAY_HOST)
        mirror_repo_path = '/home/gerrit/site_path/git/\${name}.git'
        url = '%s:%s' % (host, mirror_repo_path)
        self.msu.replicationModifyConfig(user, 'add', section,
                                         'projects', project)
        self.msu.replicationModifyConfig(user, 'add',
                                         section, 'url', url)
        push = '+refs/heads/*:refs/heads/*'
        self.msu.replicationModifyConfig(user, 'add',
                                         section, 'push', push)
        push = '+refs/tags/*:refs/tags/*'
        self.msu.replicationModifyConfig(user, 'add',
                                         section, 'push', push)

    def deleteConfigSection(self, user, project):
        # section name will be node name and the project
        section = 'managesf_%s' % project
        self.msu.replicationModifyConfig(user, 'remove-section', section)

    def mirror_clone_and_check_files(self, url, pname, us_files):
        retries = 0
        files = []
        while True:
            clone = self.clone(url, pname)
            # clone may fail, as mirror repo is not yet ready(i.e gerrit not
            # yet replicated the project)
            if os.path.isdir(clone):
                files = [f for f in os.listdir(clone) if not f.startswith('.')]
                shutil.rmtree(clone)
            if us_files and files:
                break
            elif retries > 30:
                break
            else:
                time.sleep(3)
                retries += 1
        if us_files:
            for f in us_files:
                self.assertIn(f, files)
            self.assertTrue((len(us_files) < len(files)))

    def test_replication(self):
        """ Test gerrit replication for review process
        """
        # Be sure the project, mirror repo, project in config don't exist
        self.deleteMirrorRepo(self.pname)
        self.deleteConfigSection(self.un, self.pname)
        self.msu.deleteProject(self.pname, self.un)

        # Create the project
        self.create_project(self.pname, self.un)

        # Create new section for this project in replication.config
        self.createConfigSection(self.un, self.pname)

        # Force gerrit to read its known_hosts file. The only
        # way to do that is by restarting gerrit. The Puppet Gerrit
        # manifest will restart gerrit if a new entry in known_hosts_gerrit
        # is discovered.
        # This may take some time (gerrit in some condition take long
        # to be fully up)
        call("ssh [email protected] systemctl restart gerrit", shell=True)
        call("ssh [email protected] /root/wait4gerrit.sh", shell=True)

        # Clone the project and submit it for review
        priv_key_path = set_private_key(config.USERS[self.un]["privkey"])
        gitu = GerritGitUtils(self.un,
                              priv_key_path,
                              config.USERS[self.un]['email'])
        url = "ssh://%s@%s:29418/%s" % (self.un, config.GATEWAY_HOST,
                                        self.pname)
        clone_dir = gitu.clone(url, self.pname)

        gitu.add_commit_and_publish(clone_dir, "master", "Test commit")

        # Add 2 files and resubmit for review
        data = "echo Working"
        us_files = ["run_functional-tests.sh", "run_tests.sh"]

        for f in us_files:
            file(os.path.join(clone_dir, f), 'w').write(data)
            os.chmod(os.path.join(clone_dir, f), 0755)

        gitu.add_commit_and_publish(clone_dir, "master", None, fnames=us_files)

        # Review the patch and merge it
        change_ids = self.gu.get_my_changes_for_project(self.pname)
        self.assertGreater(len(change_ids), 0)
        change_id = change_ids[0]
        self.gu.submit_change_note(change_id, "current", "Code-Review", "2")
        self.gu.submit_change_note(change_id, "current", "Verified", "2")
        self.gu.submit_change_note(change_id, "current", "Workflow", "1")
        # Put USER_2 as core for config project
        grp_name = '%s-core' % self.pname
        self.gu.add_group_member(config.USER_2, grp_name)
        self.gu2.submit_change_note(change_id, "current", "Code-Review", "2")
        self.assertTrue(self.gu.submit_patch(change_id, "current"))
        shutil.rmtree(clone_dir)

        # Verify if gerrit automatically triggered replication
        # Mirror repo(in mysql node) should have these latest changes
        # Clone the mirror repo(from mysql) and check for the 2 files
        msql_repo_url = self.msql_repo_path + '%s.git' % self.pname
        self.mirror_clone_and_check_files(msql_repo_url, self.pname, us_files)
コード例 #15
0
class TestGerritHooks(Base):
    """ Functional tests that validate Gerrit hooks.
    """
    @classmethod
    def setUpClass(cls):
        cls.msu = ManageSfUtils(config.GATEWAY_URL)

    @classmethod
    def tearDownClass(cls):
        pass

    def setUp(self):
        self.projects = []
        self.dirs_to_delete = []
        self.issues = []
        self.u = config.ADMIN_USER
        self.u2 = config.USER_2
        self.rm = RedmineUtils(
            config.GATEWAY_URL + "/redmine/",
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
        self.gu = GerritUtils(config.GATEWAY_URL,
                              auth_cookie=config.USERS[self.u]['auth_cookie'])
        self.gu2 = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[self.u2]['auth_cookie'])
        self.gu.add_pubkey(config.USERS[self.u]["pubkey"])
        priv_key_path = set_private_key(config.USERS[self.u]["privkey"])
        self.gitu = GerritGitUtils(self.u, priv_key_path,
                                   config.USERS[self.u]['email'])

    def tearDown(self):
        for issue in self.issues:
            self.rm.delete_issue(issue)
        for name in self.projects:
            self.msu.deleteProject(name, self.u)
        for dirs in self.dirs_to_delete:
            shutil.rmtree(dirs)

    def create_project(self, name, user, options=None):
        self.msu.createProject(name, user, options)
        self.projects.append(name)

    def _test_update_issue_hooks(self, comment_template, status):
        """ A referenced issue in commit msg triggers the hook
        """
        pname = 'p_%s' % create_random_str()

        # Be sure the project does not exist
        self.msu.deleteProject(pname, self.u)

        # Create the project
        self.create_project(pname, self.u)
        # Put USER_2 as core for the project
        self.gu.add_group_member(self.u2, "%s-core" % pname)

        # Create an issue on the project
        issue_id = self.rm.create_issue(pname, "There is a problem")

        # Clone and commit something
        url = "ssh://%s@%s:29418/%s" % (self.u, config.GATEWAY_HOST, pname)
        clone_dir = self.gitu.clone(url, pname)
        cmt_msg = comment_template % issue_id
        self.gitu.add_commit_and_publish(clone_dir, 'master', cmt_msg)

        # Check issue status (Gerrit hook updates the issue to in progress)
        attempt = 0
        while True:
            if self.rm.test_issue_status(issue_id, 'In Progress'):
                break
            if attempt > 10:
                break
            time.sleep(1)
            attempt += 1
        self.assertTrue(self.rm.test_issue_status(issue_id, 'In Progress'))
        self._test_merging(pname, issue_id, status)

    def _test_merging(self, pname, issue_id, status):
        # Get the change id and merge the patch
        change_ids = self.gu.get_my_changes_for_project(pname)
        self.assertGreater(len(change_ids), 0)
        change_id = change_ids[0]
        self.gu.submit_change_note(change_id, "current", "Code-Review", "2")
        self.gu.submit_change_note(change_id, "current", "Workflow", "1")
        self.gu.submit_change_note(change_id, "current", "Verified", "2")
        self.gu2.submit_change_note(change_id, "current", "Code-Review", "2")
        self.assertTrue(self.gu.submit_patch(change_id, "current"))

        # Check issue status (Gerrit hook updates the issue to in progress)
        attempt = 0
        while True:
            if self.rm.test_issue_status(issue_id, status):
                break
            if attempt > 10:
                break
            time.sleep(1)
            attempt += 1
        self.assertTrue(self.rm.test_issue_status(issue_id, status))

    def test_gerrit_hook(self):
        """test various commit messages triggering a hook"""
        for template, final_status in TEST_MSGS:
            self._test_update_issue_hooks(template, final_status)
コード例 #16
0
class TestProjectTestsWorkflow(Base):
    """ Functional tests to verify the configuration of a project test
    """
    @classmethod
    def setUpClass(cls):
        cls.ru = ResourcesUtils()
        cls.sample_project_dir = \
            os.path.join(config.SF_TESTS_DIR, "sample_project/")

    @classmethod
    def tearDownClass(cls):
        pass

    def setUp(self):
        super(TestProjectTestsWorkflow, self).setUp()
        self.projects = []
        self.dirs_to_delete = []
        self.un = config.ADMIN_USER
        self.gu = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[self.un]['auth_cookie'])
        self.gu2 = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[config.USER_2]['auth_cookie'])
        self.ju = JenkinsUtils()
        self.gu.add_pubkey(config.USERS[self.un]["pubkey"])
        priv_key_path = set_private_key(config.USERS[self.un]["privkey"])
        self.gitu_admin = GerritGitUtils(self.un,
                                         priv_key_path,
                                         config.USERS[self.un]['email'])
        # Clone the config repo and keep job/zuul config content
        self.config_clone_dir = self.clone_as_admin("config")
        self.original_zuul_projects = file(os.path.join(
            self.config_clone_dir, "zuul/projects.yaml")).read()
        self.original_project = file(os.path.join(
            self.config_clone_dir, "jobs/projects.yaml")).read()
        self.need_restore_config_repo = False
        # Put USER_2 as core for config project
        self.gu.add_group_member(config.USER_2, "config-core")

    def tearDown(self):
        super(TestProjectTestsWorkflow, self).tearDown()
        if self.need_restore_config_repo:
            self.restore_config_repo(self.original_project,
                                     self.original_zuul_projects)
        for name in self.projects:
            self.ru.direct_delete_repo(name)
        for dirs in self.dirs_to_delete:
            shutil.rmtree(dirs)

    def assert_reviewer_approvals(self, change_id, value):
        approvals = {}
        for _ in range(300):
            approvals = self.gu.get_reviewer_approvals(change_id,
                                                       'jenkins')
            if approvals and approvals.get('Verified') == value:
                break
            time.sleep(1)
        self.assertEqual(value, approvals.get('Verified'))

    def clone_as_admin(self, pname):
        url = "ssh://%s@%s:29418/%s" % (self.un, config.GATEWAY_HOST,
                                        pname)
        clone_dir = self.gitu_admin.clone(url, pname)
        if os.path.dirname(clone_dir) not in self.dirs_to_delete:
            self.dirs_to_delete.append(os.path.dirname(clone_dir))
        return clone_dir

    def restore_config_repo(self, project, zuul):
        logger.info("Restore {zuul,jobs}/projects.yaml")
        file(os.path.join(
            self.config_clone_dir, "zuul/projects.yaml"), 'w').write(
            zuul)
        file(os.path.join(
            self.config_clone_dir, "jobs/projects.yaml"), 'w').write(
            project)
        change_sha = self.commit_direct_push_as_admin(
            self.config_clone_dir,
            "Restore {zuul,jobs}/projects.yaml")
        logger.info("Waiting for config-update on %s" % change_sha)
        self.ju.wait_for_config_update(change_sha)

    def commit_direct_push_as_admin(self, clone_dir, msg):
        # Stage, commit and direct push the additions on master
        self.gitu_admin.add_commit_for_all_new_additions(clone_dir, msg)
        return self.gitu_admin.direct_push_branch(clone_dir, 'master')

    def push_review_as_admin(self, clone_dir, msg):
        # Stage, commit and direct push the additions on master
        self.gitu_admin.add_commit_for_all_new_additions(clone_dir, msg)
        return self.gitu_admin.review_push_branch(clone_dir, 'master')

    def create_project(self, name):
        self.ru.direct_create_repo(name)
        self.projects.append(name)

    def test_timestamped_logs(self):
        """Test that jenkins timestamps logs"""
        # Done here to make sure a config-update job was run and to avoid
        # duplicating code
        timestamp_re = re.compile('\d{2}:\d{2}:\d{2}.\d{0,3}')
        n = self.ju.get_last_build_number("config-update",
                                          "lastBuild")
        cu_logs = self.ju.get_job_logs("config-update",
                                       n)
        self.assertTrue(cu_logs is not None)
        for l in cu_logs.split('\n'):
            if l:
                self.assertRegexpMatches(l, timestamp_re, msg=l)

    def test_check_project_test_workflow(self):
        """ Validate new project to test via zuul
        """
        # We want to create a project, provide project source
        # code with tests. We then configure zuul/jjb to handle the
        # run of the test cases. We then validate Gerrit has been
        # updated about the test results
        # We use the sample-project (that already exists)

        pname = 'test_workflow_%s' % create_random_str()
        logger.info("Creating project %s" % pname)

        # Create it
        self.create_project(pname)

        logger.info("Populating the project with %s" %
                    self.sample_project_dir)
        # Add the sample-project to the empty repository
        clone_dir = self.clone_as_admin(pname)
        copytree(self.sample_project_dir, clone_dir)
        self.commit_direct_push_as_admin(clone_dir, "Add the sample project")

        # Change to config/{zuul,jobs}/projects.yaml
        # in order to test the new project
        logger.info("Adding config-repo configuration")
        ycontent = file(os.path.join(
            self.config_clone_dir, "zuul/projects.yaml")).read()
        file(os.path.join(
            self.config_clone_dir, "zuul/projects.yaml"), 'w').write(
            ycontent.replace("zuul-demo", pname),
        )
        ycontent2 = load(file(os.path.join(
            self.config_clone_dir, "jobs/projects.yaml")).read())
        sp2 = copy.deepcopy(
            [p for p in ycontent2 if 'project' in p and
                p['project']['name'] == 'zuul-demo'][0])
        sp2['project']['name'] = pname
        ycontent2.append(sp2)
        file(os.path.join(
            self.config_clone_dir, "jobs/projects.yaml"), 'w').write(
            dump(ycontent2))

        # Send review (config-check) will be triggered
        logger.info("Submitting the config review")
        change_sha = self.push_review_as_admin(
            self.config_clone_dir,
            "Add config definition in Zuul/JJB config for %s" % pname)

        change_nr = self.gu.get_change_number(change_sha)

        logger.info("Waiting for verify +1 on change %d" % change_nr)
        self.assertEquals(self.gu.wait_for_verify(change_nr), 1)

        # review the config change as a member from the config-core group
        logger.info("Approving and waiting for verify +2")
        self.gu2.submit_change_note(change_nr, "current", "Code-Review", "2")
        self.gu2.submit_change_note(change_nr, "current", "Workflow", "1")

        for retry in xrange(60):
            jenkins_vote = self.gu.get_vote(change_nr, "Verified")
            if jenkins_vote == 2:
                break
            time.sleep(1)
        self.assertEquals(jenkins_vote, 2)

        # verify whether zuul merged the patch
        logger.info("Waiting for change to be merged")
        for retry in xrange(60):
            change_status = self.gu.get_info(change_nr)['status']
            if change_status == "MERGED":
                break
            time.sleep(1)
        self.assertEqual(change_status, 'MERGED')
        self.need_restore_config_repo = True

        logger.info("Waiting for config-update")
        config_update_log = self.ju.wait_for_config_update(change_sha)
        self.assertIn("Finished: SUCCESS", config_update_log)

        # Propose a change on a the repo and expect a Verified +1
        logger.info("Submiting a test change to %s" % pname)
        change_sha = self.gitu_admin.add_commit_and_publish(
            clone_dir, 'master', "Add useless file",
            self.un)

        change_nr = self.gu.get_change_number(change_sha)

        logger.info("Waiting for verify +1 on change %d" % change_nr)
        self.assertEquals(self.gu.wait_for_verify(change_nr), 1)

        # Update the change on a the repo and expect a Verified -1
        logger.info("Submiting a test change to %s suppose to fail" % pname)
        data = "#!/bin/bash\nexit 1\n"
        file(os.path.join(clone_dir, "run_tests.sh"), 'w').write(data)
        os.chmod(os.path.join(clone_dir, "run_tests.sh"), 0755)
        self.gitu_admin.add_commit_and_publish(
            clone_dir, "master", None, fnames=["run_tests.sh"])

        logger.info("Waiting for verify -1 on change %d" % change_nr)
        self.assertEquals(self.gu.wait_for_verify(change_nr), -1)

        logger.info("Validate jobs ran via the job api %s" % pname)
        # This piece of code is there by convenience ...
        # TODO: Should be moved in the job api tests file.
        # Test the manageSF jobs API: query per patch & revision
        change_ids = self.gu.get_my_changes_for_project(pname)
        self.assertGreater(len(change_ids), 0)
        change_id = change_ids[0]
        patch = self.gu.get_change_last_patchset(change_id)['_number']
        cookie = get_cookie(config.ADMIN_USER, config.ADMIN_PASSWORD)
        cookies = {"auth_pubtkt": cookie}
        base_url = config.GATEWAY_URL + "/manage/jobs/"
        for j in ["%s-functional-tests" % pname, "%s-unit-tests" % pname]:
            job = requests.get(base_url + '%s/?change=%s' % (j, patch),
                               cookies=cookies).json()
            self.assertTrue("jenkins" in job.keys(),
                            job)
            self.assertTrue(len(job["jenkins"]) > 1,
                            job)
コード例 #17
0
class TestProjectReplication(Base):
    """ Functional tests to verify the gerrit replication feature
    """
    def setUp(self):
        super(TestProjectReplication, self).setUp()
        self.ru = ResourcesUtils()
        self.un = config.ADMIN_USER
        self.ju = JenkinsUtils()
        self.gu = GerritUtils(config.GATEWAY_URL,
                              auth_cookie=config.USERS[self.un]['auth_cookie'])
        self.gu2 = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[config.USER_2]['auth_cookie'])
        self.k_idx = self.gu2.add_pubkey(config.USERS[config.USER_2]["pubkey"])
        priv_key_path = set_private_key(config.USERS[self.un]["privkey"])
        self.gitu_admin = GerritGitUtils(self.un, priv_key_path,
                                         config.USERS[self.un]['email'])

        # Prepare environment for git clone on mirror repo
        self.mt = Tool()
        self.mt_tempdir = tempfile.mkdtemp()
        # Copy the service private key in a flat file
        priv_key = file(config.SERVICE_PRIV_KEY_PATH, 'r').read()
        priv_key_path = os.path.join(self.mt_tempdir, 'user.priv')
        file(priv_key_path, 'w').write(priv_key)
        os.chmod(priv_key_path, stat.S_IREAD | stat.S_IWRITE)
        # Prepare the ssh wrapper script
        ssh_wrapper = "ssh -o StrictHostKeyChecking=no -i %s \"$@\"" % (
            priv_key_path)
        wrapper_path = os.path.join(self.mt_tempdir, 'ssh_wrapper.sh')
        file(wrapper_path, 'w').write(ssh_wrapper)
        os.chmod(wrapper_path, stat.S_IRWXU)
        # Set the wrapper as GIT_SSH env variable
        self.mt.env['GIT_SSH'] = wrapper_path

        self.config_clone_dir = None

        # Project we are going to configure the replication for
        self.pname = 'test/replication'

        # Remove artifacts of previous run if any
        self.delete_config_section(self.un, self.pname)
        self.delete_mirror_repo(self.pname)

    def tearDown(self):
        super(TestProjectReplication, self).tearDown()
        self.delete_config_section(self.un, self.pname)
        self.delete_mirror_repo(self.pname)
        self.ru.direct_delete_repo(self.pname)
        self.gu2.del_pubkey(self.k_idx)

    def clone(self, uri, target):
        self.assertTrue(uri.startswith('ssh://'))
        cmd = "git clone %s %s" % (uri, target)
        clone = os.path.join(self.mt_tempdir, target)
        if os.path.isdir(clone):
            shutil.rmtree(clone)
        self.mt.exe(cmd, self.mt_tempdir)
        return clone

    def create_project(self, name):
        logger.info("Create repo to for testing replication %s" % name)
        self.ru.direct_create_repo(name)

    def ssh_run_cmd(self, sshkey_priv_path, user, host, subcmd):
        host = '%s@%s' % (user, host)
        sshcmd = [
            'ssh', '-o', 'LogLevel=ERROR', '-o', 'StrictHostKeyChecking=no',
            '-o', 'UserKnownHostsFile=/dev/null', '-i', sshkey_priv_path, host
        ]
        cmd = sshcmd + subcmd

        p = Popen(cmd, stdout=PIPE)
        return p.communicate(), p.returncode

    def delete_mirror_repo(self, name):
        logger.info("Delete mirror repo created by the replication")
        mirror_path = '/var/lib/gerrit/tmp/%s.git' % name
        cmd = [
            'ssh',
            'gerrit.%s' % config.GATEWAY_HOST, 'rm', '-rf', mirror_path
        ]
        self.ssh_run_cmd(config.SERVICE_PRIV_KEY_PATH, 'root',
                         config.GATEWAY_HOST, cmd)

    def create_config_section(self, project):
        logger.info("Add the replication config section")
        host = '%s@%s' % (config.GERRIT_USER, config.GATEWAY_HOST)
        mirror_repo_path = '/var/lib/gerrit/tmp/\${name}.git'
        url = '%s:%s' % (host, mirror_repo_path)
        path = os.path.join(self.config_clone_dir, 'gerrit/replication.config')
        call("git config -f %s --remove-section remote.test_project" % path,
             shell=True)
        call("git config -f %s --add remote.test_project.projects %s" %
             (path, project),
             shell=True)
        call("git config -f %s --add remote.test_project.url %s" % (path, url),
             shell=True)
        self.gitu_admin.add_commit_for_all_new_additions(
            self.config_clone_dir, "Add replication test section")
        # The direct push will trigger the config-update job
        # as we commit through 29418
        change_sha = self.gitu_admin.direct_push_branch(
            self.config_clone_dir, 'master')
        logger.info("Waiting for config-update on %s" % change_sha)
        self.ju.wait_for_config_update(change_sha)
        cmd = [
            'ssh',
            'gerrit.%s' % config.GATEWAY_HOST, 'grep', 'test_project',
            '/etc/gerrit/replication.config'
        ]
        logger.info("Wait for the replication config section to land")
        _, code = self.ssh_run_cmd(config.SERVICE_PRIV_KEY_PATH, 'root',
                                   config.GATEWAY_HOST, cmd)
        if code == 0:
            return
        raise Exception('replication.config file has not been updated (add)')

    def delete_config_section(self, user, project):
        logger.info("Remove the replication config section")
        url = "ssh://%s@%s:29418/config" % (self.un, config.GATEWAY_HOST)
        self.config_clone_dir = self.gitu_admin.clone(url,
                                                      'config',
                                                      config_review=True)
        sha = open("%s/.git/refs/heads/master" %
                   self.config_clone_dir).read().strip()
        path = os.path.join(self.config_clone_dir, 'gerrit/replication.config')
        call("git config -f %s --remove-section remote.test_project" % path,
             shell=True)
        change_sha = self.gitu_admin.add_commit_for_all_new_additions(
            self.config_clone_dir, "Remove replication test section")
        # The direct push will trigger the config-update job
        # as we commit through 29418
        if change_sha == sha:
            # Nothing have been changed/Nothing to publish
            return
        change_sha = self.gitu_admin.direct_push_branch(
            self.config_clone_dir, 'master')
        logger.info("Waiting for config-update on %s" % change_sha)
        self.ju.wait_for_config_update(change_sha)
        cmd = [
            'ssh',
            'gerrit.%s' % config.GATEWAY_HOST, 'grep', 'test_project',
            '/etc/gerrit/replication.config'
        ]
        _, code = self.ssh_run_cmd(config.SERVICE_PRIV_KEY_PATH, 'root',
                                   config.GATEWAY_HOST, cmd)
        if code != 0:
            return
        raise Exception('replication.config has not been updated (rm)')

    def mirror_clone_and_check_files(self, url, pname):
        for retry in xrange(50):
            clone = self.clone(url, pname)
            # clone may fail, as mirror repo is not yet ready(i.e gerrit not
            # yet replicated the project)
            if os.path.isdir(clone):
                logger.info("Files in the mirror repo: %s" % os.listdir(clone))
            if os.path.isdir(clone) and \
               os.path.isfile(os.path.join(clone, '.gitreview')):
                break
            else:
                time.sleep(3)
        self.assertTrue(os.path.exists(os.path.join(clone, '.gitreview')))

    def test_replication(self):
        """ Test gerrit replication for review process
        """
        # Create the project
        self.create_project(self.pname)

        # Be sure sftests.com host key is inside the known_hosts
        cmds = [[
            'ssh',
            'gerrit.%s' % config.GATEWAY_HOST, 'ssh-keyscan', 'sftests.com',
            '>', '/var/lib/gerrit/.ssh/known_hosts'
        ]]
        for cmd in cmds:
            self.ssh_run_cmd(config.SERVICE_PRIV_KEY_PATH, 'root',
                             config.GATEWAY_HOST, cmd)

        # Create new section for this project in replication.config
        self.create_config_section(self.pname)

        # Verify if gerrit replicated the repo
        self.managesf_repo_path = "ssh://%s@%s/var/lib/gerrit/tmp/" % (
            'root', config.GATEWAY_HOST)
        repo_url = self.managesf_repo_path + '%s.git' % self.pname
        logger.info("Wait for the replication to happen")
        self.mirror_clone_and_check_files(repo_url, self.pname)
コード例 #18
0
    def test_check_add_automatic_reviewers(self):
        """ Test if reviewers-by-blame plugin works
        """
        pname = 'p_%s' % create_random_str()
        u2mail = config.USERS[config.USER_2]['email']
        options = {'core-group': u2mail}
        self.create_project(pname, options)
        first_u = config.ADMIN_USER
        gu_first_u = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[first_u]['auth_cookie'])
        self.assertTrue(gu_first_u.project_exists(pname))
        # Push data in the create project as Admin user
        k1_index = gu_first_u.add_pubkey(config.USERS[first_u]["pubkey"])
        priv_key_path = set_private_key(config.USERS[first_u]["privkey"])
        gitu = GerritGitUtils(first_u, priv_key_path,
                              config.USERS[first_u]['email'])
        url = "ssh://%s@%s:29418/%s" % (first_u, config.GATEWAY_HOST, pname)
        clone_dir = gitu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))
        data = ['this', 'is', 'a', 'couple', 'of', 'lines']
        clone_dir = gitu.clone(url, pname)
        file(os.path.join(clone_dir, "file"), 'w').write("\n".join(data))
        gitu.add_commit_and_publish(clone_dir,
                                    "master",
                                    "Test commit",
                                    fnames=["file"])
        # Get the change id
        change_ids = gu_first_u.get_my_changes_for_project(pname)
        self.assertEqual(len(change_ids), 1)
        change_id = change_ids[0]
        # Merge the change
        gu_first_u.submit_change_note(change_id, "current", "Code-Review", "2")
        gu_first_u.submit_change_note(change_id, "current", "Verified", "2")
        gu_first_u.submit_change_note(change_id, "current", "Workflow", "1")
        second_u = config.USER_2
        gu_second_u = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[second_u]['auth_cookie'])
        self.assertTrue(gu_first_u.submit_patch(change_id, "current"))
        # Change the file we have commited with Admin user
        k2_index = gu_second_u.add_pubkey(config.USERS[second_u]["pubkey"])
        priv_key_path = set_private_key(config.USERS[second_u]["privkey"])
        gitu = GerritGitUtils(second_u, priv_key_path,
                              config.USERS[second_u]['email'])
        url = "ssh://%s@%s:29418/%s" % (second_u, config.GATEWAY_HOST, pname)
        clone_dir = gitu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))
        data = ['this', 'is', 'some', 'lines']
        file(os.path.join(clone_dir, "file"), 'w').write("\n".join(data))
        gitu.add_commit_and_publish(clone_dir,
                                    "master",
                                    "Test commit",
                                    fnames=["file"])
        # Get the change id
        change_ids = gu_second_u.get_my_changes_for_project(pname)
        self.assertEqual(len(change_ids), 1)
        change_id = change_ids[0]
        # Verify first_u has been automatically added to reviewers
        attempts = 0
        while True:
            if len(gu_second_u.get_reviewers(change_id)) > 0 or attempts >= 3:
                break
            attempts += 1
            time.sleep(1)
        reviewers = gu_second_u.get_reviewers(change_id)
        self.assertGreaterEqual(len(reviewers), 1)
        self.assertTrue(first_u in reviewers)

        gu_first_u.del_pubkey(k1_index)
        gu_second_u.del_pubkey(k2_index)
コード例 #19
0
class TestProjectReplication(Base):
    """ Functional tests to verify the gerrit replication feature
    """
    def setUp(self):
        self.msu = ManageSfUtils(config.GATEWAY_URL)
        self.un = config.ADMIN_USER
        self.gu = GerritUtils(config.GATEWAY_URL,
                              auth_cookie=config.USERS[self.un]['auth_cookie'])
        self.gu2 = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[config.USER_2]['auth_cookie'])
        self.k_idx = self.gu2.add_pubkey(config.USERS[config.USER_2]["pubkey"])
        priv_key_path = set_private_key(config.USERS[self.un]["privkey"])
        self.gitu_admin = GerritGitUtils(self.un, priv_key_path,
                                         config.USERS[self.un]['email'])
        # Configuration to access mirror repo present in managesf
        self.managesf_repo_path = "ssh://%s@%s/home/gerrit/git/" % (
            config.GERRIT_USER, config.GATEWAY_HOST)
        # prepare environment for git clone on mirror repo
        self.mt = Tool()
        self.mt_tempdir = tempfile.mkdtemp()
        priv_key = file(config.GERRIT_SERVICE_PRIV_KEY_PATH, 'r').read()
        priv_key_path = os.path.join(self.mt_tempdir, 'user.priv')
        file(priv_key_path, 'w').write(priv_key)
        os.chmod(priv_key_path, stat.S_IREAD | stat.S_IWRITE)
        ssh_wrapper = "ssh -o StrictHostKeyChecking=no -i %s \"$@\"" % (
            priv_key_path)
        wrapper_path = os.path.join(self.mt_tempdir, 'ssh_wrapper.sh')
        file(wrapper_path, 'w').write(ssh_wrapper)
        os.chmod(wrapper_path, stat.S_IRWXU)
        self.mt.env['GIT_SSH'] = wrapper_path
        self.pname = 'test-replication'

    def tearDown(self):
        self.deleteConfigSection(self.un, self.pname)
        self.deleteMirrorRepo(self.pname)
        self.msu.deleteProject(self.pname, self.un)
        self.gu2.del_pubkey(self.k_idx)

    # Can't use GerritGitUtils.clone as not sure when source uri repo
    # be ready.(i.e gerrit is taking time to create the mirror repo in managesf
    # node) So this clone may succeed or fail, we don't need 'git review -s'
    # and other review commands in clone method
    def clone(self, uri, target):
        self.assertTrue(uri.startswith('ssh://'))
        cmd = "git clone %s %s" % (uri, target)
        self.mt.exe(cmd, self.mt_tempdir)
        clone = os.path.join(self.mt_tempdir, target)
        return clone

    def create_project(self, name, user, options=None):
        self.msu.createProject(name, user, options)

    def ssh_run_cmd(self, sshkey_priv_path, user, host, subcmd):
        host = '%s@%s' % (user, host)
        sshcmd = [
            'ssh', '-o', 'LogLevel=ERROR', '-o', 'StrictHostKeyChecking=no',
            '-o', 'UserKnownHostsFile=/dev/null', '-i', sshkey_priv_path, host
        ]
        cmd = sshcmd + subcmd

        p = Popen(cmd, stdout=PIPE)
        return p.communicate()

    def deleteMirrorRepo(self, name):
        sshkey_priv_path = config.GERRIT_SERVICE_PRIV_KEY_PATH
        user = '******'
        host = config.GATEWAY_HOST
        mirror_path = '/home/gerrit/git/%s.git' % name
        cmd = ['rm', '-rf', mirror_path]
        self.ssh_run_cmd(sshkey_priv_path, user, host, cmd)

    def createConfigSection(self, user, project):
        # Section name will be node name and the project
        section = 'managesf_%s' % project
        host = '%s@%s' % (config.GERRIT_USER, config.GATEWAY_HOST)
        mirror_repo_path = '/home/gerrit/git/\${name}.git'
        url = '%s:%s' % (host, mirror_repo_path)
        self.msu.replicationModifyConfig(user, 'add', section, 'projects',
                                         project)
        self.msu.replicationModifyConfig(user, 'add', section, 'url', url)
        push = '+refs/heads/*:refs/heads/*'
        self.msu.replicationModifyConfig(user, 'add', section, 'push', push)
        push = '+refs/tags/*:refs/tags/*'
        self.msu.replicationModifyConfig(user, 'add', section, 'push', push)

    def deleteConfigSection(self, user, project):
        # section name will be node name and the project
        section = 'managesf_%s' % project
        self.msu.replicationModifyConfig(user, 'remove', section)

    def mirror_clone_and_check_files(self, url, pname, us_files):
        retries = 0
        files = []
        while True:
            clone = self.clone(url, pname)
            # clone may fail, as mirror repo is not yet ready(i.e gerrit not
            # yet replicated the project)
            if os.path.isdir(clone):
                files = [f for f in os.listdir(clone) if not f.startswith('.')]
                shutil.rmtree(clone)
            if us_files and files:
                break
            elif retries > 30:
                break
            else:
                time.sleep(3)
                retries += 1
        if us_files:
            for f in us_files:
                self.assertIn(f, files)
            self.assertTrue((len(us_files) < len(files)))

    def test_replication(self):
        """ Test gerrit replication for review process
        """
        # Be sure the project, mirror repo, project in config don't exist
        self.deleteMirrorRepo(self.pname)
        self.deleteConfigSection(self.un, self.pname)
        self.msu.deleteProject(self.pname, self.un)

        # Create the project
        self.create_project(self.pname, self.un)

        # Create new section for this project in replication.config
        self.createConfigSection(self.un, self.pname)

        # Force gerrit to read its known_hosts file. The only
        # way to do that is by restarting gerrit. The Puppet Gerrit
        # manifest will restart gerrit if a new entry in known_hosts_gerrit
        # is discovered.
        # This may take some time (gerrit in some condition take long
        # to be fully up)
        call("ssh %s ssh gerrit systemctl restart gerrit" %
             config.GATEWAY_HOST,
             shell=True)
        call("ssh %s ssh gerrit /root/wait4gerrit.sh" % config.GATEWAY_HOST,
             shell=True)

        # Clone the project and submit it for review
        priv_key_path = set_private_key(config.USERS[self.un]["privkey"])
        gitu = GerritGitUtils(self.un, priv_key_path,
                              config.USERS[self.un]['email'])
        url = "ssh://%s@%s:29418/%s" % (self.un, config.GATEWAY_HOST,
                                        self.pname)
        clone_dir = gitu.clone(url, self.pname)

        gitu.add_commit_and_publish(clone_dir, "master", "Test commit")

        # Add 2 files and resubmit for review
        data = "echo Working"
        us_files = ["run_functional-tests.sh", "run_tests.sh"]

        for f in us_files:
            file(os.path.join(clone_dir, f), 'w').write(data)
            os.chmod(os.path.join(clone_dir, f), 0755)

        gitu.add_commit_and_publish(clone_dir, "master", None, fnames=us_files)

        # Review the patch and merge it
        change_ids = self.gu.get_my_changes_for_project(self.pname)
        self.assertGreater(len(change_ids), 0)
        change_id = change_ids[0]
        self.gu.submit_change_note(change_id, "current", "Code-Review", "2")
        self.gu.submit_change_note(change_id, "current", "Verified", "2")
        self.gu.submit_change_note(change_id, "current", "Workflow", "1")
        # Put USER_2 as core for config project
        grp_name = '%s-core' % self.pname
        self.gu.add_group_member(config.USER_2, grp_name)
        self.gu2.submit_change_note(change_id, "current", "Code-Review", "2")
        self.assertTrue(self.gu.submit_patch(change_id, "current"))
        shutil.rmtree(clone_dir)

        # Verify if gerrit automatically triggered replication
        repo_url = self.managesf_repo_path + '%s.git' % self.pname
        self.mirror_clone_and_check_files(repo_url, self.pname, us_files)
コード例 #20
0
class TestProjectReplication(Base):
    """ Functional tests to verify the gerrit replication feature
    """
    def setUp(self):
        self.msu = ManageSfUtils(config.GATEWAY_URL)
        self.un = config.ADMIN_USER
        self.gu = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[self.un]['auth_cookie'])
        self.gu2 = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[config.USER_2]['auth_cookie'])
        self.k_idx = self.gu2.add_pubkey(config.USERS[config.USER_2]["pubkey"])
        priv_key_path = set_private_key(config.USERS[self.un]["privkey"])
        self.gitu_admin = GerritGitUtils(self.un,
                                         priv_key_path,
                                         config.USERS[self.un]['email'])

        # Prepare environment for git clone on mirror repo
        self.mt = Tool()
        self.mt_tempdir = tempfile.mkdtemp()
        # Copy the service private key in a flat file
        priv_key = file(config.SERVICE_PRIV_KEY_PATH, 'r').read()
        priv_key_path = os.path.join(self.mt_tempdir, 'user.priv')
        file(priv_key_path, 'w').write(priv_key)
        os.chmod(priv_key_path, stat.S_IREAD | stat.S_IWRITE)
        # Prepare the ssh wrapper script
        ssh_wrapper = "ssh -o StrictHostKeyChecking=no -i %s \"$@\"" % (
            priv_key_path)
        wrapper_path = os.path.join(self.mt_tempdir, 'ssh_wrapper.sh')
        file(wrapper_path, 'w').write(ssh_wrapper)
        os.chmod(wrapper_path, stat.S_IRWXU)
        # Set the wrapper as GIT_SSH env variable
        self.mt.env['GIT_SSH'] = wrapper_path

        self.config_clone_dir = None

        # Project we are going to configure the replication for
        self.pname = 'test/replication'

        # Remove artifacts of previous run if any
        self.delete_config_section(self.un, self.pname)
        self.delete_mirror_repo(self.pname)

    def tearDown(self):
        self.delete_config_section(self.un, self.pname)
        self.delete_mirror_repo(self.pname)
        self.msu.deleteProject(self.pname, self.un)
        self.gu2.del_pubkey(self.k_idx)

    def clone(self, uri, target):
        self.assertTrue(uri.startswith('ssh://'))
        cmd = "git clone %s %s" % (uri, target)
        clone = os.path.join(self.mt_tempdir, target)
        if os.path.isdir(clone):
            shutil.rmtree(clone)
        self.mt.exe(cmd, self.mt_tempdir)
        return clone

    def create_project(self, name, user, options=None):
        self.msu.createProject(name, user, options)

    def ssh_run_cmd(self, sshkey_priv_path, user, host, subcmd):
        host = '%s@%s' % (user, host)
        sshcmd = ['ssh', '-o', 'LogLevel=ERROR',
                  '-o', 'StrictHostKeyChecking=no',
                  '-o', 'UserKnownHostsFile=/dev/null', '-i',
                  sshkey_priv_path, host]
        cmd = sshcmd + subcmd

        p = Popen(cmd, stdout=PIPE)
        return p.communicate(), p.returncode

    def delete_mirror_repo(self, name):
        mirror_path = '/home/gerrit/git/%s.git' % name
        cmd = ['ssh', 'gerrit.%s' % config.GATEWAY_HOST,
               'rm', '-rf', mirror_path]
        self.ssh_run_cmd(config.SERVICE_PRIV_KEY_PATH,
                         'root',
                         config.GATEWAY_HOST, cmd)

    def create_config_section(self, project):
        host = '%s@%s' % (config.GERRIT_USER, config.GATEWAY_HOST)
        mirror_repo_path = '/home/gerrit/git/\${name}.git'
        url = '%s:%s' % (host, mirror_repo_path)
        path = os.path.join(self.config_clone_dir,
                            'gerrit/replication.config')
        call("git config -f %s --remove-section remote.test_project" %
             path, shell=True)
        call("git config -f %s --add remote.test_project.projects %s" %
             (path, project), shell=True)
        call("git config -f %s --add remote.test_project.url %s" %
             (path, url), shell=True)
        self.gitu_admin.add_commit_for_all_new_additions(
            self.config_clone_dir, "Add replication test section")
        # The direct push will trigger the config-update job
        # as we commit through 29418
        self.gitu_admin.direct_push_branch(self.config_clone_dir, 'master')
        attempts = 0
        cmd = ['ssh', 'gerrit.%s' % config.GATEWAY_HOST, 'grep',
               'test_project', '/home/gerrit/site_path/etc/replication.config']
        while attempts < 30:
            out, code = self.ssh_run_cmd(config.SERVICE_PRIV_KEY_PATH,
                                         'root',
                                         config.GATEWAY_HOST, cmd)
            if code == 0:
                return
            attempts += 1
            time.sleep(2)
        raise Exception('replication.config file has not been updated (add)')

    def delete_config_section(self, user, project):
        url = "ssh://%s@%s:29418/config" % (self.un, config.GATEWAY_HOST)
        self.config_clone_dir = self.gitu_admin.clone(
            url, 'config', config_review=True)
        path = os.path.join(self.config_clone_dir, 'gerrit/replication.config')
        call("git config -f %s --remove-section remote.test_project" %
             path, shell=True)
        try:
            self.gitu_admin.add_commit_for_all_new_additions(
                self.config_clone_dir, "Remove replication test section")
        except CalledProcessError:
            # We fail if nothing to re-initialized
            return
        # The direct push will trigger the config-update job
        # as we commit through 29418
        self.gitu_admin.direct_push_branch(self.config_clone_dir, 'master')
        attempts = 0
        cmd = ['ssh', 'gerrit.%s' % config.GATEWAY_HOST, 'grep',
               'test_project',
               '/home/gerrit/site_path/etc/replication.config']
        while attempts < 30:
            out, code = self.ssh_run_cmd(config.SERVICE_PRIV_KEY_PATH,
                                         'root',
                                         config.GATEWAY_HOST, cmd)
            if code != 0:
                return
            attempts += 1
            time.sleep(2)
        raise Exception('replication.config has not been updated (rm)')

    def mirror_clone_and_check_files(self, url, pname):
        retries = 0
        while True:
            clone = self.clone(url, pname)
            # clone may fail, as mirror repo is not yet ready(i.e gerrit not
            # yet replicated the project)
            if os.path.isdir(clone) and \
               os.path.isfile(os.path.join(clone, '.gitreview')):
                return True
            elif retries > 50:
                break
            else:
                time.sleep(3)
                retries += 1
        return False

    def test_replication(self):
        """ Test gerrit replication for review process
        """
        # Create the project
        self.create_project(self.pname, self.un)

        # Be sure sftests.com host key is inside the known_hosts
        cmds = [['ssh', 'gerrit.%s' % config.GATEWAY_HOST,
                 'ssh-keyscan', 'sftests.com', '>',
                 '/home/gerrit/.ssh/known_hosts']]
        for cmd in cmds:
            self.ssh_run_cmd(config.SERVICE_PRIV_KEY_PATH,
                             'root',
                             config.GATEWAY_HOST, cmd)

        # Create new section for this project in replication.config
        self.create_config_section(self.pname)

        # Verify if gerrit replicated the repo
        self.managesf_repo_path = "ssh://%s@%s/home/gerrit/git/" % (
            'root', config.GATEWAY_HOST)
        repo_url = self.managesf_repo_path + '%s.git' % self.pname
        self.assertTrue(self.mirror_clone_and_check_files(repo_url,
                                                          self.pname))
コード例 #21
0
    def test_check_zuul_operations(self):
        """ Test if zuul verifies project correctly through zuul-demo project
        """
        # zuul-demo - test project used exclusively to test zuul installation
        # The necessary project descriptions are already declared in Jenkins
        # and zuul
        pname = 'zuul-demo'
        self.create_project(pname, config.ADMIN_USER)
        un = config.ADMIN_USER
        gu = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[un]['auth_cookie'])
        ju = JenkinsUtils()
        k_index = gu.add_pubkey(config.USERS[un]["pubkey"])
        # Gerrit part
        self.assertTrue(gu.project_exists(pname))
        priv_key_path = set_private_key(config.USERS[un]["privkey"])
        gitu = GerritGitUtils(un,
                              priv_key_path,
                              config.USERS[un]['email'])
        url = "ssh://%s@%s:29418/%s" % (un, config.GATEWAY_HOST,
                                        pname)
        clone_dir = gitu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))

        last_fail_build_num_ft = \
            ju.get_last_build_number("zuul-demo-functional-tests",
                                     "lastFailedBuild")
        last_fail_build_num_ut = \
            ju.get_last_build_number("zuul-demo-unit-tests",
                                     "lastFailedBuild")
        last_succeed_build_num_ft = \
            ju.get_last_build_number("zuul-demo-functional-tests",
                                     "lastSuccessfulBuild")
        last_succeed_build_num_ut = \
            ju.get_last_build_number("zuul-demo-unit-tests",
                                     "lastSuccessfulBuild")

        gitu.add_commit_and_publish(clone_dir, "master", "Test commit")

        change_ids = gu.get_my_changes_for_project(pname)
        self.assertEqual(len(change_ids), 1)
        change_id = change_ids[0]

        # Give some time for jenkins to work
        ju.wait_till_job_completes("zuul-demo-functional-tests",
                                   last_fail_build_num_ft, "lastFailedBuild")
        ju.wait_till_job_completes("zuul-demo-unit-tests",
                                   last_fail_build_num_ut, "lastFailedBuild")

        attempt = 0
        while "jenkins" not in gu.get_reviewers(change_id):
            if attempt >= 90:
                break
            time.sleep(1)
            attempt += 1

        attempt = 0
        while gu.get_reviewer_approvals(change_id, 'jenkins')['Verified'] \
                != '-1':
            if attempt >= 90:
                break
            time.sleep(1)
            attempt += 1

        self.assertEqual(
            gu.get_reviewer_approvals(change_id, 'jenkins')['Verified'], '-1')

        # Add the test case files and resubmit for review
        data = "echo Working"
        files = ["run_functional-tests.sh", "run_tests.sh"]

        for f in files:
            file(os.path.join(clone_dir, f), 'w').write(data)
            os.chmod(os.path.join(clone_dir, f), 0755)

        gitu.add_commit_and_publish(clone_dir, "master", None, fnames=files)

        # Give some time for jenkins to work
        ju.wait_till_job_completes("zuul-demo-functional-tests",
                                   last_succeed_build_num_ft,
                                   "lastSuccessfulBuild")
        ju.wait_till_job_completes("zuul-demo-unit-tests",
                                   last_succeed_build_num_ut,
                                   "lastSuccessfulBuild")

        attempt = 0
        while "jenkins" not in gu.get_reviewers(change_id):
            if attempt >= 90:
                break
            time.sleep(1)
            attempt += 1

        attempt = 0
        while gu.get_reviewer_approvals(change_id, 'jenkins')['Verified'] \
                != '+1':
            if attempt >= 90:
                break
            time.sleep(1)
            attempt += 1

        self.assertEqual(
            gu.get_reviewer_approvals(change_id, 'jenkins')['Verified'], '+1')

        gu.del_pubkey(k_index)
コード例 #22
0
class TestGerritHooks(Base):
    """ Functional tests that validate Gerrit hooks.
    """
    @classmethod
    def setUpClass(cls):
        cls.msu = ManageSfUtils(config.GATEWAY_URL)

    @classmethod
    def tearDownClass(cls):
        pass

    def setUp(self):
        self.projects = []
        self.dirs_to_delete = []
        self.issues = []
        self.u = config.ADMIN_USER
        self.u2 = config.USER_2
        self.rm = RedmineUtils(
            config.GATEWAY_URL + "/redmine/",
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
        self.gu = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[self.u]['auth_cookie'])
        self.gu2 = GerritUtils(
            config.GATEWAY_URL,
            auth_cookie=config.USERS[self.u2]['auth_cookie'])
        self.gu.add_pubkey(config.USERS[self.u]["pubkey"])
        priv_key_path = set_private_key(config.USERS[self.u]["privkey"])
        self.gitu = GerritGitUtils(self.u,
                                   priv_key_path,
                                   config.USERS[self.u]['email'])

    def tearDown(self):
        for issue in self.issues:
            self.rm.delete_issue(issue)
        for name in self.projects:
            self.msu.deleteProject(name, self.u)
        for dirs in self.dirs_to_delete:
            shutil.rmtree(dirs)

    def create_project(self, name, user,
                       options=None):
        self.msu.createProject(name, user,
                               options)
        self.projects.append(name)

    def _test_update_issue_hooks(self, comment_template, status):
        """ A referenced issue in commit msg triggers the hook
        """
        pname = 'p_%s' % create_random_str()

        # Be sure the project does not exist
        self.msu.deleteProject(pname, self.u)

        # Create the project
        self.create_project(pname, self.u)
        # Put USER_2 as core for the project
        self.gu.add_group_member(self.u2, "%s-core" % pname)

        # Create an issue on the project
        issue_id = self.rm.create_issue(pname, "There is a problem")

        # Clone and commit something
        url = "ssh://%s@%s:29418/%s" % (self.u, config.GATEWAY_HOST,
                                        pname)
        clone_dir = self.gitu.clone(url, pname)
        cmt_msg = comment_template % issue_id
        self.gitu.add_commit_and_publish(clone_dir, 'master', cmt_msg)

        # Check issue status (Gerrit hook updates the issue to in progress)
        attempt = 0
        while True:
            if self.rm.test_issue_status(issue_id, 'In Progress'):
                break
            if attempt > 10:
                break
            time.sleep(1)
            attempt += 1
        self.assertTrue(self.rm.test_issue_status(issue_id, 'In Progress'))
        self._test_merging(pname, issue_id, status)

    def _test_merging(self, pname, issue_id, status):
        # Get the change id and merge the patch
        change_ids = self.gu.get_my_changes_for_project(pname)
        self.assertGreater(len(change_ids), 0)
        change_id = change_ids[0]
        self.gu.submit_change_note(change_id, "current", "Code-Review", "2")
        self.gu.submit_change_note(change_id, "current", "Workflow", "1")
        self.gu.submit_change_note(change_id, "current", "Verified", "2")
        self.gu2.submit_change_note(change_id, "current", "Code-Review", "2")
        self.assertTrue(self.gu.submit_patch(change_id, "current"))

        # Check issue status (Gerrit hook updates the issue to in progress)
        attempt = 0
        while True:
            if self.rm.test_issue_status(issue_id, status):
                break
            if attempt > 10:
                break
            time.sleep(1)
            attempt += 1
        self.assertTrue(self.rm.test_issue_status(issue_id, status))

    def test_gerrit_hook(self):
        """test various commit messages triggering a hook"""
        for template, final_status in TEST_MSGS:
            self._test_update_issue_hooks(template, final_status)
コード例 #23
0
class TestGerritHooks(Base):
    """ Functional tests that validate Gerrit hooks.
    """
    @classmethod
    def setUpClass(cls):
        cls.msu = ManageSfUtils(config.GATEWAY_URL)

    @classmethod
    def tearDownClass(cls):
        pass

    def setUp(self):
        super(TestGerritHooks, self).setUp()
        self.projects = []
        self.dirs_to_delete = []
        self.issues = []
        self.u = config.ADMIN_USER
        self.rm = get_issue_tracker_utils(
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
        self.gu = GerritUtils(config.GATEWAY_URL,
                              auth_cookie=config.USERS[self.u]['auth_cookie'])
        self.gu.add_pubkey(config.USERS[self.u]["pubkey"])
        priv_key_path = set_private_key(config.USERS[self.u]["privkey"])
        self.gitu = GerritGitUtils(self.u, priv_key_path,
                                   config.USERS[self.u]['email'])

    def tearDown(self):
        super(TestGerritHooks, self).tearDown()
        for issue in self.issues:
            self.rm.delete_issue(issue)
        for name in self.projects:
            self.msu.deleteProject(name, self.u)
        for dirs in self.dirs_to_delete:
            shutil.rmtree(dirs)

    def create_project(self, name, user, options=None):
        self.msu.createProject(name, user, options)
        self.projects.append(name)

    def _test_update_issue_hooks(self, comment_template, status, pname):
        """ A referenced issue in commit msg triggers the hook
        """
        # Be sure the project does not exist
        self.msu.deleteProject(pname, self.u)

        # Create the project
        self.create_project(pname, self.u)

        # Create an issue on the project
        issue_id = self.rm.create_issue(pname, "There is a problem")

        # Clone and commit something
        url = "ssh://%s@%s:29418/%s" % (self.u, config.GATEWAY_HOST, pname)
        clone_dir = self.gitu.clone(url, pname)
        cmt_msg = comment_template % issue_id
        self.gitu.add_commit_and_publish(clone_dir, 'master', cmt_msg)

        # Check issue status (Gerrit hook updates the issue to in progress)
        for retry in xrange(10):
            if self.rm.test_issue_status(issue_id, 'In Progress'):
                break
            time.sleep(1)
        self.assertTrue(self.rm.test_issue_status(issue_id, 'In Progress'))
        self._test_merging(pname, issue_id, status)

    def _test_merging(self, pname, issue_id, status):
        # Get the change id and merge the patch
        change_ids = self.gu.get_my_changes_for_project(pname)
        self.assertGreater(len(change_ids), 0)
        change_id = change_ids[0]
        self.gu.submit_change_note(change_id, "current", "Code-Review", "2")
        self.gu.submit_change_note(change_id, "current", "Workflow", "1")
        self.gu.submit_change_note(change_id, "current", "Verified", "2")
        self.assertTrue(self.gu.submit_patch(change_id, "current"))

        # Check issue status (Gerrit hook updates the issue to in progress)
        for retry in xrange(10):
            if self.rm.test_issue_status(issue_id, status):
                break
            time.sleep(1)
        self.assertTrue(self.rm.test_issue_status(issue_id, status))

    @skipIfIssueTrackerMissing()
    def test_gerrit_hook(self):
        """test various commit messages triggering a hook"""
        for template, final_status in TEST_MSGS:
            pname = 'my_namespace/%s' % create_random_str()
            self._test_update_issue_hooks(template, final_status, pname)

    @skipIfIssueTrackerMissing()
    def test_gerrit_hook_double_quotes(self):
        """test commit messages with double quotes"""
        for template, final_status in TEST_MSGS:
            verbose_template = """Super fix

This fix solves the Universe. Not just the "Universe", the Universe.
"""
            verbose_template += template
            pname = 'p_%s' % create_random_str()
            self._test_update_issue_hooks(verbose_template, final_status,
                                          pname)