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')))
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')))
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
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)
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
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)
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)
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)
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)
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
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)
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')
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)
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)
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)
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)
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)
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)
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))
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)
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)
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)