def setUp(self):
     self.projects = []
     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[config.ADMIN_USER]['auth_cookie'])
 def project_exists_ex(self, name, user):
     # Test here the project is "public"
     # ( Redmine API project detail does not return the private/public flag)
     rm = RedmineUtils(config.GATEWAY_URL + "/redmine/", auth_cookie=config.USERS[user]["auth_cookie"])
     try:
         return rm.project_exists(name)
     except Exception:
         return False
Beispiel #3
0
 def register_new_user(self, user):
     r = RedmineUtils(self.conf['apiurl'],
                      key=self.conf['apikey'])
     try:
         r.create_user(user['login'],
                       user['email'],
                       user['name'])
     except Exception as e:
         raise base.UserRegistrationError(e.message)
 def project_exists_ex(self, name, user):
     # Test here the project is "public"
     # ( Redmine API project detail does not return the private/public flag)
     rm = RedmineUtils(config.GATEWAY_URL + "/redmine/",
                       auth_cookie=config.USERS[user]['auth_cookie'])
     try:
         return rm.project_exists(name)
     except Exception:
         return False
Beispiel #5
0
 def __init__(self, cli_options=None, conf_file=None):
     self.command_line_options = cli_options or DEFAULT_CLI_OPTIONS
     self.conf_file = conf_file
     self.config = yaml.load(conf_file)
     self.redmine_client = RedmineUtils(self.config['redmine_url'],
                                        key=self.config['redmine_key'])
     bottom_url = "/r/gitweb?p=%(project)s;a=commit;h=%(commit)s"
     self.gitweb_url = urllib_parse.urljoin(self.config['gitweb_url'],
                                            bottom_url)
Beispiel #6
0
 def __init__(self):
     with open("%s/resources.yaml" % pwd, 'r') as rsc:
         self.resources = yaml.load(rsc)
     config.USERS[config.ADMIN_USER]['auth_cookie'] = get_cookie(
         config.ADMIN_USER, config.USERS[config.ADMIN_USER]['password'])
     self.msu = ManageSfUtils(config.GATEWAY_URL)
     self.ggu = GerritGitUtils(config.ADMIN_USER,
                               config.ADMIN_PRIV_KEY_PATH,
                               config.USERS[config.ADMIN_USER]['email'])
     self.ju = JenkinsUtils()
     self.rm = RedmineUtils(
         config.GATEWAY_URL + "/redmine/",
         auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
 def setUp(self):
     self.projects = []
     self.dirs_to_delete = []
     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[config.ADMIN_USER]["auth_cookie"])
 def setUp(self):
     self.projects = []
     self.rm = RedmineUtils(
         config.REDMINE_URL,
         auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
     self.gu = GerritUtils(
         'https://%s/' % config.GATEWAY_HOST,
         auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
Beispiel #9
0
def get_issue_tracker_utils(*args, **kwargs):
    """Returns the correct utility instance depending on the issue tracker
    being deployed with Software Factory"""
    if 'redmine' in services:
        return RedmineUtils(config.GATEWAY_URL + "/redmine/", *args, **kwargs)
    else:
        from pysflib.interfaces.issuetracker import IssueTrackerUtils
        return IssueTrackerUtils(config.GATEWAY_URL, *args, **kwargs)
Beispiel #10
0
 def __init__(self, cli_options=None, conf_file=None):
     self.command_line_options = cli_options or DEFAULT_CLI_OPTIONS
     self.conf_file = conf_file
     self.config = yaml.load(conf_file)
     self.redmine_client = RedmineUtils(self.config['redmine_url'],
                                        key=self.config['redmine_key'])
     bottom_url = "/r/gitweb?p=%(project)s;a=commit;h=%(commit)s"
     self.gitweb_url = urllib_parse.urljoin(self.config['gitweb_url'],
                                            bottom_url)
 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 __init__(self):
     with open('resources.yaml', 'r') as rsc:
         self.resources = yaml.load(rsc)
     config.USERS[config.ADMIN_USER]['auth_cookie'] = get_cookie(
         config.ADMIN_USER, config.USERS[config.ADMIN_USER]['password'])
     self.msu = ManageSfUtils(config.GATEWAY_URL)
     self.ggu = GerritGitUtils(config.ADMIN_USER,
                               config.ADMIN_PRIV_KEY_PATH,
                               config.USERS[config.ADMIN_USER]['email'])
     self.ju = JenkinsUtils()
     self.rm = RedmineUtils(
         config.REDMINE_URL,
         auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
Beispiel #13
0
 def __init__(self):
     with open("%s/resources.yaml" % pwd, 'r') as rsc:
         self.resources = yaml.load(rsc)
     config.USERS[config.ADMIN_USER]['auth_cookie'] = get_cookie(
         config.ADMIN_USER, config.USERS[config.ADMIN_USER]['password'])
     self.gu = GerritUtils(
         'http://%s/' % config.GATEWAY_HOST,
         auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
     self.ggu = GerritGitUtils(config.ADMIN_USER,
                               config.ADMIN_PRIV_KEY_PATH,
                               config.USERS[config.ADMIN_USER]['email'])
     self.ju = JenkinsUtils()
     self.rm = RedmineUtils(
         config.GATEWAY_URL + "/redmine/",
         auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
 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'])
class TestManageSF(Base):
    """ Functional tests that validate managesf features.
    Here we do basic verifications about project creation
    with managesf.
    """
    @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.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[config.ADMIN_USER]['auth_cookie'])

    def project_exists_ex(self, name, user):
        # Test here the project is "public"
        # ( Redmine API project detail does not return the private/public flag)
        rm = RedmineUtils(
            config.GATEWAY_URL + "/redmine/",
            auth_cookie=config.USERS[user]['auth_cookie'])
        try:
            return rm.project_exists(name)
        except Exception:
            return False

    def tearDown(self):
        for name in self.projects:
            self.msu.deleteProject(name,
                                   config.ADMIN_USER)
        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_create_public_project_as_admin(self):
        """ Create public project on redmine and gerrit as admin
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-core' % pname))
        # Redmine part
        if is_present("SFRedmine"):
            self.assertTrue(self.rm.project_exists(pname))
            self.assertTrue(
                self.rm.check_user_role(pname, config.ADMIN_USER, 'Manager'))
            self.assertTrue(
                self.rm.check_user_role(pname, config.ADMIN_USER, 'Developer'))
            self.assertTrue(self.project_exists_ex(pname, config.USER_2))

    def test_create_private_project_as_admin(self):
        """ Create private project on redmine and gerrit as admin
        """
        pname = 'p_%s' % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.ADMIN_USER,
                            options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        self.assertTrue(self.gu.group_exists('%s-dev' % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-core' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-dev' % pname))
        # Redmine part
        if is_present("SFRedmine"):
            self.assertTrue(self.rm.project_exists(pname))
            self.assertTrue(
                self.rm.check_user_role(pname, config.ADMIN_USER, 'Manager'))
            self.assertTrue(
                self.rm.check_user_role(pname, config.ADMIN_USER, 'Developer'))
            self.assertFalse(self.project_exists_ex(pname, config.USER_2))

    def test_delete_public_project_as_admin(self):
        """ Delete public project on redmine and gerrit as admin
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        self.assertTrue(self.gu.project_exists(pname))
        if is_present("SFRedmine"):
            self.assertTrue(self.rm.project_exists(pname))
        self.msu.deleteProject(pname, config.ADMIN_USER)
        self.assertFalse(self.gu.project_exists(pname))
        self.assertFalse(self.gu.group_exists('%s-ptl' % pname))
        if is_present("SFRedmine"):
            self.assertFalse(self.rm.project_exists(pname))
        self.assertFalse(self.gu.group_exists('%s-core' % pname))
        self.projects.remove(pname)

    def test_create_public_project_as_user(self):
        """ Create public project on redmine and gerrit as user
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.USER_2)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-core' % pname))
        # Redmine part
        if is_present("SFRedmine"):
            self.assertTrue(self.rm.project_exists(pname))
            self.assertTrue(self.project_exists_ex(pname, config.USER_2))
            self.assertTrue(
                self.rm.check_user_role(pname, config.USER_2, 'Manager'))
            self.assertTrue(
                self.rm.check_user_role(pname, config.USER_2, 'Developer'))
            self.assertTrue(self.project_exists_ex(pname, config.USER_3))

    def test_create_private_project_as_user(self):
        """ Create private project on redmine and gerrit as user
        """
        pname = 'p_%s' % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.USER_2,
                            options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        self.assertTrue(self.gu.group_exists('%s-dev' % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.USER_2, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.USER_2, '%s-core' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.USER_2, '%s-dev' % pname))
        # Redmine part
        if is_present("SFRedmine"):
            self.assertTrue(self.rm.project_exists(pname))
            self.assertTrue(self.project_exists_ex(pname, config.USER_2))
            self.assertTrue(
                self.rm.check_user_role(pname, config.USER_2, 'Manager'))
            self.assertTrue(
                self.rm.check_user_role(pname, config.USER_2, 'Developer'))
            self.assertFalse(self.project_exists_ex(pname, config.USER_3))

    def test_create_public_project_with_users_in_group(self):
        """ Create public project on redmine and gerrit with users in groups
        """
        pname = 'p_%s' % create_random_str()
        u2mail = config.USERS[config.USER_2]['email']
        u3mail = config.USERS[config.USER_3]['email']
        options = {"ptl-group": "",
                   "core-group": "%s,%s" % (u2mail, u3mail),
                   }
        self.create_project(pname, config.ADMIN_USER,
                            options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        for user in (config.ADMIN_USER, config.USER_2, config.USER_3):
            self.assertTrue(self.gu.member_in_group(user, '%s-core' % pname))
        if is_present("SFRedmine"):
            self.assertTrue(self.rm.project_exists(pname))
            self.assertTrue(
                self.rm.check_user_role(pname, config.ADMIN_USER, 'Manager'))
            for user in (config.ADMIN_USER, config.USER_2, config.USER_3):
                self.assertTrue(self.rm.check_user_role(pname,
                                                        user,
                                                        'Developer'))

    def test_create_private_project_with_users_in_group(self):
        """ Create private project on redmine and gerrit with users in groups
        """
        pname = 'p_%s' % create_random_str()
        u2mail = config.USERS[config.USER_2]['email']
        u3mail = config.USERS[config.USER_3]['email']
        u4mail = config.USERS[config.USER_4]['email']
        options = {"private": "",
                   "ptl-group": "",
                   "core-group": "%s,%s" % (u2mail, u3mail),
                   "dev-group": "%s" % u4mail,
                   }
        self.create_project(pname, config.ADMIN_USER,
                            options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        for user in (config.ADMIN_USER, config.USER_2, config.USER_3):
            self.assertTrue(self.gu.member_in_group(user, '%s-core' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.USER_4, '%s-dev' % pname))
        # Redmine part
        if is_present("SFRedmine"):
            # it should be visible to admin
            self.assertTrue(self.rm.project_exists(pname))
            self.assertTrue(
                self.rm.check_user_role(pname, config.ADMIN_USER, 'Manager'))
            for user in (config.ADMIN_USER, config.USER_2,
                         config.USER_3, config.USER_4):
                self.assertTrue(self.rm.check_user_role(pname, user,
                                                        'Developer'))

    def test_create_public_project_as_admin_clone_as_admin(self):
        """ Clone public project as admin and check content
        """
        pname = 'a_%s' % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        ggu = GerritGitUtils(config.ADMIN_USER,
                             config.ADMIN_PRIV_KEY_PATH,
                             config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname)
        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')))
        # Verify meta/config branch own both group and ACLs config file
        ggu.fetch_meta_config(clone_dir)
        self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                    'project.config')))
        self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                    'groups')))
        # There is no group dev for a public project
        content = file(os.path.join(clone_dir, 'project.config')).read()
        self.assertFalse('%s-dev' % pname in content)
        content = file(os.path.join(clone_dir, 'groups')).read()
        self.assertFalse('%s-dev' % pname in content)

    def test_create_private_project_as_admin_clone_as_admin(self):
        """ Clone private project as admin and check content
        """
        pname = 'p_%s' % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.ADMIN_USER, options=options)
        ggu = GerritGitUtils(config.ADMIN_USER,
                             config.ADMIN_PRIV_KEY_PATH,
                             config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname)
        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')))
        # Verify meta/config branch own both group and ACLs config file
        ggu.fetch_meta_config(clone_dir)
        self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                    'project.config')))
        self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                    'groups')))
        # There is a group dev for a private project
        content = file(os.path.join(clone_dir, 'project.config')).read()
        self.assertTrue('%s-dev' % pname in content)
        content = file(os.path.join(clone_dir, 'groups')).read()
        self.assertTrue('%s-dev' % pname in content)

    def test_create_public_project_as_admin_clone_as_user(self):
        """ Create public project as admin then clone as user
        """
        pname = 'p_%s' % create_random_str()
        # create the project as admin
        self.create_project(pname, config.ADMIN_USER)
        # 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(
            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_upstream(self):
        """ Validate upstream feature of managesf
        """
        # Create a test upstream project
        pname_us = 'p_upstream'
        self.create_project(pname_us, config.ADMIN_USER)

        ggu_us = GerritGitUtils(config.ADMIN_USER,
                                config.ADMIN_PRIV_KEY_PATH,
                                config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname_us)
        # clone
        us_clone_dir = ggu_us.clone(url, pname_us)
        self.dirs_to_delete.append(os.path.dirname(us_clone_dir))
        # Test that the clone is a success
        self.assertTrue(os.path.isdir(us_clone_dir))
        # push some test files to the upstream project
        us_files = [str(x) for x in range(1, 10)]
        for f in us_files:
            file(os.path.join(us_clone_dir, f), 'w').write(f)
            os.chmod(os.path.join(us_clone_dir, f), 0755)

        ggu_us.add_commit_in_branch(us_clone_dir, "master",
                                    commit="Adding files 1-10",
                                    files=us_files)
        ggu_us.direct_push_branch(us_clone_dir, "master")
        ggu_us.add_commit_in_branch(us_clone_dir, "branch1")
        ggu_us.direct_push_branch(us_clone_dir, "branch1")

        # No create a test project with upstream pointing to the above
        upstream_url = "ssh://%s@%s:29418/%s" % (
            config.ADMIN_USER, config.GATEWAY_HOST, pname_us)
        pname = 'p_%s' % create_random_str()
        # create the project as admin
        options = {"upstream": upstream_url,
                   "upstream-ssh-key": config.ADMIN_PRIV_KEY_PATH}
        self.create_project(pname, config.ADMIN_USER, options=options)

        ggu = GerritGitUtils(config.ADMIN_USER,
                             config.ADMIN_PRIV_KEY_PATH,
                             config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname)
        # clone
        clone_dir = ggu.clone(url, pname)

        # Check if the files pushed in upstream project is present
        files = [f for f in os.listdir(clone_dir) if not f.startswith('.')]
        self.assertEqual(set(files), set(us_files))
        branches = ggu.get_branches(clone_dir, True)
        self.assertNotIn('gerrit/branch1', branches)

        # Test upstream with additional branches
        pname2 = 'p_%s' % create_random_str()
        options['add-branches'] = ''
        self.create_project(pname2, config.ADMIN_USER, options=options)
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname2)
        clone_dir = ggu.clone(url, pname2)
        branches = ggu.get_branches(clone_dir, True)
        self.assertIn('gerrit/branch1', branches)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))

    def test_delete_project_as_admin(self):
        """ Check if admin can delete projects that are not owned by admin
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.USER_2)
        self.assertTrue(self.gu.project_exists(pname))
        if is_present("SFRedmine"):
            self.assertTrue(self.rm.project_exists(pname))
        self.msu.deleteProject(pname, config.ADMIN_USER)
        self.assertFalse(self.gu.project_exists(pname))
        self.assertFalse(self.gu.group_exists('%s-ptl' % pname))
        if is_present("SFRedmine"):
            self.assertFalse(self.rm.project_exists(pname))
        self.assertFalse(self.gu.group_exists('%s-core' % pname))
        self.projects.remove(pname)

    def test_basic_ops_project_namespace(self):
        """ Check if a project named with a / (namespace) is handled
        correctly on basic ops by managesf
        """
        pname = 'skydive/%s' % create_random_str()
        self.create_project(pname, config.USER_2)
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        if is_present("SFRedmine"):
            rname = '_'.join(pname.split('/'))
            self.assertTrue(self.rm.project_exists(rname))
        # Try to clone
        ggu = GerritGitUtils(config.ADMIN_USER,
                             config.ADMIN_PRIV_KEY_PATH,
                             config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname)
        clone_dir = ggu.clone(url, pname.split('/')[-1])
        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')))
        # Delete the project from SF
        self.msu.deleteProject(pname, config.ADMIN_USER)
        self.assertFalse(self.gu.project_exists(pname))
        self.assertFalse(self.gu.group_exists('%s-ptl' % pname))
        if is_present("SFRedmine"):
            rname = '_'.join(pname.split('/'))
            self.assertFalse(self.rm.project_exists(rname))
        self.assertFalse(self.gu.group_exists('%s-core' % pname))

        # Clean local clone directory
        self.projects.remove(pname)

    # For now listing users comes from Redmine
    @skipIfIssueTrackerMissing()
    def test_list_active_members(self):
        """ Check the list of members as a list of tuples of emails and names
        """
        self.assertTrue(self.msu.list_active_members(config.USER_2))

    def test_init_user_tests(self):
        """ Check if a test init feature behave as expected
        """
        project = 'p_%s' % create_random_str()
        self.create_project(project, config.USER_4)
        self.msu.create_init_tests(project, config.USER_4)
        ggu = GerritGitUtils(config.ADMIN_USER,
                             config.ADMIN_PRIV_KEY_PATH,
                             config.USERS[config.ADMIN_USER]['email'])
        open_reviews = ggu.list_open_reviews('config', config.GATEWAY_HOST)
        match = [True for review in open_reviews if review['commitMessage'].
                 startswith("%s proposes initial test "
                            "definition for project %s" %
                            (config.USER_4, project))]
        self.assertEqual(len(match), 1)
        open_reviews = ggu.list_open_reviews(project, config.GATEWAY_HOST)
        match = [True for review in open_reviews if review['commitMessage'].
                 startswith("%s proposes initial test "
                            "scripts for project %s" %
                            (config.USER_4, project))]
        self.assertEqual(len(match), 1)

    def test_rest_urls_accessible(self):
        """ Check if managesf URLs are all working
        """
        project = 'p_%s' % create_random_str()
        self.create_project(project, config.ADMIN_USER)
        cookies = dict(
            auth_pubtkt=config.USERS[config.ADMIN_USER]['auth_cookie'])
        paths = [
            "/manage/project/",
            "/manage/project/%s" % project,
            "/manage/project/membership/"]
        for path in paths:
            url = "http://%s%s" % (config.GATEWAY_HOST, path)
            resp = requests.get(url, cookies=cookies)
            self.assertEqual(200, resp.status_code)

    def test_validate_get_all_project_details(self):
        """ Check if managesf allow us to fetch projects details
        """
        project = 'p_%s' % create_random_str()
        self.create_project(project, config.USER_2)
        admin_cookies = dict(
            auth_pubtkt=config.USERS[config.ADMIN_USER]['auth_cookie'])
        user2_cookies = dict(
            auth_pubtkt=config.USERS[config.USER_2]['auth_cookie'])
        url = "http://%s%s" % (config.GATEWAY_HOST, "/manage/project/")
        resp = requests.get(url, cookies=admin_cookies)
        self.assertEqual(200, resp.status_code)
        self.assertTrue(project in resp.json())
        self.assertTrue('config' in resp.json())
        resp = requests.get(url, cookies=user2_cookies)
        self.assertEqual(200, resp.status_code)
        self.assertTrue(project in resp.json())
        self.assertTrue('config' in resp.json())
        resp = requests.get(url, cookies=user2_cookies)

        # Validate the same behavior with project including a '/'
        project = 'p/%s' % create_random_str()
        self.create_project(project, config.USER_2)
        url = "http://%s%s" % (config.GATEWAY_HOST, "/manage/project/")
        # Wait 15 seconds for managesf cache invalidation
        import time
        time.sleep(15)
        resp = requests.get(url, cookies=user2_cookies)
        self.assertEqual(200, resp.status_code)
        self.assertTrue(project in resp.json())

    def test_project_pages_config(self):
        """ Check if managesf allow us to configure pages for a project
        """
        project = 'p_%s' % create_random_str()
        self.create_project(project, config.USER_2)
        self.assertTrue(self.gu.project_exists(project))
        self.assertTrue(self.rm.project_exists(project))
        self.msu.update_project_page(config.USER_2, project,
                                     "http://tests.com/")
        self.assertEqual(self.msu.get_project_page(config.USER_2,
                                                   project).strip(),
                         "\"http://tests.com/\"")
        self.msu.delete_project_page(config.USER_3, project)
        self.assertEqual(self.msu.get_project_page(config.USER_2,
                                                   project).strip(),
                         "\"http://tests.com/\"")
        self.msu.delete_project_page(config.USER_2, project)
        self.assertEqual(self.msu.get_project_page(config.USER_2,
                                                   project).strip(),
                         "")
class TestProjectMembership(Base):
    """ Functional tests that validate adding or deleting
    users to project groups using managesf.
    """

    @classmethod
    def setUpClass(cls):
        cls.msu = ManageSfUtils(config.GATEWAY_URL)

    @classmethod
    def tearDownClass(cls):
        pass

    def setUp(self):
        self.projects = []
        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[config.ADMIN_USER]["auth_cookie"])

    def tearDown(self):
        for name in self.projects:
            self.msu.deleteProject(name, config.ADMIN_USER)

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

    def test_admin_manage_project_members(self):
        """ Test admin can add and delete users from all project groups
        """
        pname = "p_%s" % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists("%s-ptl" % pname))
        self.assertTrue(self.gu.group_exists("%s-core" % pname))
        groups = "ptl-group core-group"
        # Add user2 to ptl and core groups
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname, config.USER_2, groups)
        # Test if user2 exists in ptl and core groups
        self.assertTrue(self.gu.member_in_group(config.USER_2, "%s-ptl" % pname))
        self.assertTrue(self.gu.member_in_group(config.USER_2, "%s-core" % pname))
        # Redmine part
        self.assertTrue(self.rm.check_user_role(pname, config.USER_2, "Manager"))
        self.assertTrue(self.rm.check_user_role(pname, config.USER_2, "Developer"))

        # Delete user2 from project groups
        self.msu.deleteUserFromProjectGroups(config.ADMIN_USER, pname, config.USER_2)
        # Test if user exists in ptl and core groups
        self.assertFalse(self.gu.member_in_group(config.USER_2, "%s-ptl" % pname))
        self.assertFalse(self.gu.member_in_group(config.USER_2, "%s-core" % pname))
        # Redmine part
        self.assertFalse(self.rm.check_user_role(pname, config.USER_2, "Manager"))
        self.assertFalse(self.rm.check_user_role(pname, config.USER_2, "Developer"))

    def test_ptl_manage_project_members(self):
        """ Test ptl can add and delete users from all project groups
        """
        # Let user2 create the project, so he will be ptl for this project
        pname = "p_%s" % create_random_str()
        self.create_project(pname, config.USER_2)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists("%s-ptl" % pname))
        self.assertTrue(self.gu.group_exists("%s-core" % pname))
        groups = "ptl-group core-group"

        # ptl should be ale to add users to all groups
        # so user2 should be able to add user3 to ptl and core groups
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3, groups)
        # Test if user3 exists in ptl and core groups
        self.assertTrue(self.gu.member_in_group(config.USER_3, "%s-ptl" % pname))
        self.assertTrue(self.gu.member_in_group(config.USER_3, "%s-core" % pname))
        # Redmine part
        self.assertTrue(self.rm.check_user_role(pname, config.USER_3, "Manager"))
        self.assertTrue(self.rm.check_user_role(pname, config.USER_3, "Developer"))

        # ptl should be able to remove users from all groups
        self.msu.deleteUserFromProjectGroups(config.USER_2, pname, config.USER_3)
        # user3 shouldn't exist in any group
        self.assertFalse(self.gu.member_in_group(config.USER_3, "%s-ptl" % pname))
        self.assertFalse(self.gu.member_in_group(config.USER_3, "%s-core" % pname))
        # Redmine part
        self.assertFalse(self.rm.check_user_role(pname, config.USER_3, "Manager"))
        self.assertFalse(self.rm.check_user_role(pname, config.USER_3, "Developer"))

    def test_core_manage_project_members(self):
        """ Test core can add and delete users to core group
        """
        # let admin create the project
        pname = "p_%s" % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists("%s-ptl" % pname))
        self.assertTrue(self.gu.group_exists("%s-core" % pname))
        groups = "core-group"

        # Add user2 as core user
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname, config.USER_2, groups)
        # Test if user2 exists in core group
        self.assertTrue(self.gu.member_in_group(config.USER_2, "%s-core" % pname))
        # Redmine part
        self.assertTrue(self.rm.check_user_role(pname, config.USER_2, "Developer"))

        groups = "core-group"
        # core should be ale to add users to only core group and not ptl group
        # so user2 should be able to add user3 to only core group and not
        # ptl group
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3, groups)
        # user3 should exist in core group
        self.assertTrue(self.gu.member_in_group(config.USER_3, "%s-core" % pname))
        # Redmine part
        self.assertTrue(self.rm.check_user_role(pname, config.USER_3, "Developer"))

        groups = "ptl-group"
        # core should not be allowed to add users to ptl group
        # so user2 should not be able to add user3 to ptl group
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3, groups)
        # user3 shouldn't exist in ptl group
        self.assertFalse(self.gu.member_in_group(config.USER_3, "%s-ptl" % pname))
        # Redmine part
        self.assertFalse(self.rm.check_user_role(pname, config.USER_3, "Manager"))

        # core should be able to remove users from core group
        group = "core-group"
        self.msu.deleteUserFromProjectGroups(config.USER_2, pname, config.USER_3, group)
        # user3 shouldn't exist in core group
        self.assertFalse(self.gu.member_in_group(config.USER_3, "%s-core" % pname))
        # Redmine part
        self.assertFalse(self.rm.check_user_role(pname, config.USER_3, "Developer"))

    def test_non_member_manage_project_members(self):
        """ Test non project members can add and delete users to core group
        """
        # Let admin create the project
        pname = "p_%s" % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists("%s-ptl" % pname))
        self.assertTrue(self.gu.group_exists("%s-core" % pname))

        # non project meber can't add user to core group
        # user2 can't add user3 to core group
        groups = "core-group"
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3, groups)
        # user3 shouldn't exist in core group
        self.assertFalse(self.gu.member_in_group(config.USER_3, "%s-core" % pname))
        # Redmine part
        self.assertFalse(self.rm.check_user_role(pname, config.USER_3, "Developer"))

        groups = "ptl-group"
        # non project meber can't add usr to ptl group
        # user2 can't add user3 to ptl group
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3, groups)
        # user3 shouldn't exist in ptl group
        self.assertFalse(self.gu.member_in_group(config.USER_3, "%s-ptl" % pname))
        # Redmine part
        self.assertFalse(self.rm.check_user_role(pname, config.USER_3, "Manager"))

        # non project meber can't delete usr from any group.
        # Let admin add user3 to ptl and core groups,
        # then try to remove user3 from ptl and core groups by
        # user2 (i.e non member user)
        groups = "ptl-group core-group"
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname, config.USER_3, groups)
        # non-admin user(user2) can't remove users from project groups
        self.msu.deleteUserFromProjectGroups(config.USER_2, pname, config.USER_3)
        # user3 should exist in ptl and core group
        self.assertTrue(self.gu.member_in_group(config.USER_3, "%s-ptl" % pname))
        self.assertTrue(self.gu.member_in_group(config.USER_3, "%s-core" % pname))
        # Redmine part
        self.assertTrue(self.rm.check_user_role(pname, config.USER_3, "Manager"))
        self.assertTrue(self.rm.check_user_role(pname, config.USER_3, "Developer"))

    def test_manage_project_members_for_dev_group(self):
        """ Add and Delete users from dev group by admin, ptl, core,
            dev and non members
        """
        pname = "p_%s" % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.ADMIN_USER, options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists("%s-ptl" % pname))
        self.assertTrue(self.gu.group_exists("%s-core" % pname))
        self.assertTrue(self.gu.group_exists("%s-dev" % pname))
        self.assertTrue(self.gu.member_in_group(config.ADMIN_USER, "%s-dev" % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(self.rm.check_user_role(pname, config.ADMIN_USER, "Developer"))

        # Admin should add user to dev group
        groups = "dev-group"
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname, config.USER_3, groups)
        # Test if user3 exists in dev group
        self.assertTrue(self.gu.member_in_group(config.USER_3, "%s-dev" % pname))
        # Redmine part
        self.assertTrue(self.rm.check_user_role(pname, config.USER_3, "Developer"))

        # admin should be able to remove users from dev group
        self.msu.deleteUserFromProjectGroups(config.ADMIN_USER, pname, config.USER_3)
        # user3 shouldn't exist in dev group
        self.assertFalse(self.gu.member_in_group(config.USER_3, "%s-dev" % pname))
        # Redmine part
        self.assertFalse(self.rm.check_user_role(pname, config.USER_3, "Developer"))

        # ptl should add user to dev group
        # let admin add user2 as ptl
        groups = "ptl-group"
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname, config.USER_2, groups)
        groups = "dev-group"
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3, groups)
        # Test if user3 exists in dev group
        self.assertTrue(self.gu.member_in_group(config.USER_3, "%s-dev" % pname))
        # Redmine part
        self.assertTrue(self.rm.check_user_role(pname, config.USER_3, "Developer"))

        # ptl should be able to remove users from dev group
        self.msu.deleteUserFromProjectGroups(config.USER_2, pname, config.USER_3)
        # user3 shouldn't exist in dev group
        self.assertFalse(self.gu.member_in_group(config.USER_3, "%s-dev" % pname))
        # Redmine part
        self.assertFalse(self.rm.check_user_role(pname, config.USER_3, "Developer"))
        # Remove user2 as ptl
        self.msu.deleteUserFromProjectGroups(config.ADMIN_USER, pname, config.USER_2)

        # core should add user to dev group
        # let admin add user2 as core
        groups = "core-group"
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname, config.USER_2, groups)
        groups = "dev-group"
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3, groups)
        # Test if user3 exists in dev group
        self.assertTrue(self.gu.member_in_group(config.USER_3, "%s-dev" % pname))
        # Redmine part
        self.assertTrue(self.rm.check_user_role(pname, config.USER_3, "Developer"))

        # core should be able to remove users from dev group
        group = "dev-group"
        self.msu.deleteUserFromProjectGroups(config.USER_2, pname, config.USER_3, group)
        # user3 shouldn't exist in dev group
        self.assertFalse(self.gu.member_in_group(config.USER_3, "%s-dev" % pname))
        # Redmine part
        self.assertFalse(self.rm.check_user_role(pname, config.USER_3, "Developer"))
        # Remove user2 as core
        self.msu.deleteUserFromProjectGroups(config.ADMIN_USER, pname, config.USER_2)

        # let admin add user2 as developer
        groups = "dev-group"
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname, config.USER_2, groups)
        # dev user should be able to add a new user to dev group
        groups = "dev-group"
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3, groups)
        # Test if user3 exists in dev group
        self.assertTrue(self.gu.member_in_group(config.USER_3, "%s-dev" % pname))
        # Redmine part
        self.assertTrue(self.rm.check_user_role(pname, config.USER_3, "Developer"))

        # developer should be able to remove users from dev group
        group = "dev-group"
        self.msu.deleteUserFromProjectGroups(config.USER_2, pname, config.USER_3, group)
        # user3 shouldn't exist in dev group
        self.assertFalse(self.gu.member_in_group(config.USER_3, "%s-dev" % pname))
        # Redmine part
        self.assertFalse(self.rm.check_user_role(pname, config.USER_3, "Developer"))
        # Remove user2 ifrom dev group
        self.msu.deleteUserFromProjectGroups(config.ADMIN_USER, pname, config.USER_2)
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)
Beispiel #18
0
class SFProvisioner(object):
    """ This provider is only intended for testing
    SF backup/restore and update. It provisions some
    user datas in a SF installation based on a resourses.yaml
    file. Later those data can be checked by its friend
    the SFChecker.

    Provisioned data should remain really simple.
    """
    def __init__(self):
        with open("%s/resources.yaml" % pwd, 'r') as rsc:
            self.resources = yaml.load(rsc)
        config.USERS[config.ADMIN_USER]['auth_cookie'] = get_cookie(
            config.ADMIN_USER, config.USERS[config.ADMIN_USER]['password'])
        self.msu = ManageSfUtils(config.GATEWAY_URL)
        self.ggu = GerritGitUtils(config.ADMIN_USER,
                                  config.ADMIN_PRIV_KEY_PATH,
                                  config.USERS[config.ADMIN_USER]['email'])
        self.ju = JenkinsUtils()
        self.rm = RedmineUtils(
            config.GATEWAY_URL + "/redmine/",
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])

    def create_project(self, name):
        print " Creating project %s ..." % name
        self.msu.createProject(name, config.ADMIN_USER)

    def push_files_in_project(self, name, files):
        print " Add files(%s) in a commit ..." % ",".join(files)
        # TODO(fbo); use gateway host instead of gerrit host
        self.url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                             config.GATEWAY_HOST, name)
        clone_dir = self.ggu.clone(self.url, name, config_review=False)
        self.clone_dir = clone_dir
        for f in files:
            file(os.path.join(clone_dir, f), 'w').write('data')
            self.ggu.git_add(clone_dir, (f, ))
        self.ggu.add_commit_for_all_new_additions(clone_dir)
        self.ggu.direct_push_branch(clone_dir, 'master')

    def create_issues_on_project(self, name, issues):
        print " Create %s issue(s) for that project ..." % len(issues)
        for i in issues:
            issue = self.rm.create_issue(name, i['name'])
            yield issue, i['review']

    def create_jenkins_jobs(self, name, jobnames):
        print " Create Jenkins jobs(%s)  ..." % ",".join(jobnames)
        for jobname in jobnames:
            self.ju.create_job("%s_%s" % (name, jobname))

    def create_pads(self, amount):
        # TODO
        pass

    def create_pasties(self, amount):
        # TODO
        pass

    def create_review(self, project, issue):
        """Very basic review creator for statistics and restore tests
        purposes."""
        self.ggu.config_review(self.clone_dir)
        self.ggu.add_commit_in_branch(self.clone_dir,
                                      'branch_' + issue,
                                      commit='test\n\nBug: %s' % issue)
        self.ggu.review_push_branch(self.clone_dir, 'branch_' + issue)

    def provision(self):
        for project in self.resources['projects']:
            print "Create user datas for %s" % project['name']
            self.create_project(project['name'])
            self.push_files_in_project(project['name'],
                                       [f['name'] for f in project['files']])
            for i, review in self.create_issues_on_project(
                    project['name'], project['issues']):
                if review:
                    print "Create review for bug %i in %s" % (i,
                                                              project['name'])
                    self.create_review(project['name'], str(i))
            self.create_jenkins_jobs(project['name'],
                                     [j['name'] for j in project['jobnames']])
        self.create_pads(2)
        self.create_pasties(2)
class SFProvisioner(object):
    """ This provider is only intended for testing
    SF backup/restore and update. It provisions some
    user datas in a SF installation based on a resourses.yaml
    file. Later those data can be checked by its friend
    the SFChecker.

    Provisioned data should remain really simple.
    """
    def __init__(self):
        with open("%s/resources.yaml" % pwd, 'r') as rsc:
            self.resources = yaml.load(rsc)
        config.USERS[config.ADMIN_USER]['auth_cookie'] = get_cookie(
            config.ADMIN_USER, config.USERS[config.ADMIN_USER]['password'])
        self.msu = ManageSfUtils(config.GATEWAY_URL)
        self.ggu = GerritGitUtils(config.ADMIN_USER,
                                  config.ADMIN_PRIV_KEY_PATH,
                                  config.USERS[config.ADMIN_USER]['email'])
        self.ju = JenkinsUtils()
        self.rm = RedmineUtils(
            config.GATEWAY_URL + "/redmine/",
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])

    def create_project(self, name):
        print " Creating project %s ..." % name
        self.msu.createProject(name, config.ADMIN_USER)

    def push_files_in_project(self, name, files):
        print " Add files(%s) in a commit ..." % ",".join(files)
        # TODO(fbo); use gateway host instead of gerrit host
        self.url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                             config.GATEWAY_HOST, name)
        clone_dir = self.ggu.clone(self.url, name, config_review=False)
        self.clone_dir = clone_dir
        for f in files:
            file(os.path.join(clone_dir, f), 'w').write('data')
            self.ggu.git_add(clone_dir, (f,))
        self.ggu.add_commit_for_all_new_additions(clone_dir)
        self.ggu.direct_push_branch(clone_dir, 'master')

    def create_issues_on_project(self, name, issues):
        print " Create %s issue(s) for that project ..." % len(issues)
        for i in issues:
            if is_present('SFRedmine'):
                issue = self.rm.create_issue(name, i['name'])
            else:
                issue = random.randint(1,100)
            yield issue, i['review']

    def create_jenkins_jobs(self, name, jobnames):
        print " Create Jenkins jobs(%s)  ..." % ",".join(jobnames)
        for jobname in jobnames:
            self.ju.create_job("%s_%s" % (name, jobname))

    def create_pads(self, amount):
        # TODO
        pass

    def create_pasties(self, amount):
        # TODO
        pass


    def simple_login(self, user):
        """log as user to make the user listable"""
        get_cookie(user, config.USERS[user]['password'])


    def create_review(self, project, issue):
        """Very basic review creator for statistics and restore tests
        purposes."""
        self.ggu.config_review(self.clone_dir)
        self.ggu.add_commit_in_branch(self.clone_dir,
                                      'branch_' + issue,
                                      commit='test\n\nBug: %s' % issue)
        self.ggu.review_push_branch(self.clone_dir, 'branch_' + issue)

    def create_local_user(self, username, password, email):
        self.msu.create_user(username, password, email)

    def command(self, cmd):
        return ssh_run_cmd(os.path.expanduser("~/.ssh/id_rsa"),
                           "root",
                           config.GATEWAY_HOST, shlex.split(cmd))

    def compute_checksum(self, f):
        out = self.command("md5sum %s" % f)[0]
        if out:
            return out.split()[0]

    def provision(self):
        for cmd in self.resources['commands']:
            print "Execute command %s" % cmd['cmd']
            print self.command(cmd['cmd'])
        checksum_list = {}
        for checksum in self.resources['checksum'] :
            print "Compute checksum for file %s" % checksum['file']
            checksum_list[checksum['file']] = self.compute_checksum(
                checksum['file'])
        yaml.dump(checksum_list, file('/tmp/pc_checksums.yaml', 'w'))
        for user in self.resources['local_users']:
            print "Create local user %s" % user['username']
            self.create_local_user(user['username'],
                                   user['password'],
                                   user['email'])
        for u in self.resources['users']:
            print "log in as %s" % u['name']
            self.simple_login(u['name'])
        for project in self.resources['projects']:
            print "Create user datas for %s" % project['name']
            self.create_project(project['name'])
            self.push_files_in_project(project['name'],
                                       [f['name'] for f in project['files']])
            for i, review in self.create_issues_on_project(project['name'],
                                                           project['issues']):
                if review:
                    print "Create review for bug %i in %s" % (i,
                                                              project['name'])
                    self.create_review(project['name'], str(i))
            self.create_jenkins_jobs(project['name'],
                                     [j['name'] for j in project['jobnames']])
        self.create_pads(2)
        self.create_pasties(2)
class TestProjectMembership(Base):
    """ Functional tests that validate adding or deleting
    users to project groups using managesf.
    """
    @classmethod
    def setUpClass(cls):
        cls.msu = ManageSfUtils(config.GATEWAY_URL)

    @classmethod
    def tearDownClass(cls):
        pass

    def setUp(self):
        self.projects = []
        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[config.ADMIN_USER]['auth_cookie'])

    def tearDown(self):
        for name in self.projects:
            self.msu.deleteProject(name, config.ADMIN_USER)

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

    def test_admin_manage_project_members(self):
        """ Test admin can add and delete users from all project groups
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        groups = 'ptl-group core-group'
        # Add user2 to ptl and core groups
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname,
                                        config.USER_2, groups)
        # Test if user2 exists in ptl and core groups
        self.assertTrue(
            self.gu.member_in_group(config.USER_2, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.USER_2, '%s-core' % pname))
        # Redmine part
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_2, 'Manager'))
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_2, 'Developer'))

        # Delete user2 from project groups
        self.msu.deleteUserFromProjectGroups(config.ADMIN_USER, pname,
                                             config.USER_2)
        # Test if user exists in ptl and core groups
        self.assertFalse(
            self.gu.member_in_group(config.USER_2, '%s-ptl' % pname))
        self.assertFalse(
            self.gu.member_in_group(config.USER_2, '%s-core' % pname))
        # Redmine part
        self.assertFalse(
            self.rm.check_user_role(pname, config.USER_2, 'Manager'))
        self.assertFalse(
            self.rm.check_user_role(pname, config.USER_2, 'Developer'))

    def test_ptl_manage_project_members(self):
        """ Test ptl can add and delete users from all project groups
        """
        # Let user2 create the project, so he will be ptl for this project
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.USER_2)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        groups = 'ptl-group core-group'

        # ptl should be ale to add users to all groups
        # so user2 should be able to add user3 to ptl and core groups
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3,
                                        groups)
        # Test if user3 exists in ptl and core groups
        self.assertTrue(
            self.gu.member_in_group(config.USER_3, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.USER_3, '%s-core' % pname))
        # Redmine part
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_3, 'Manager'))
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))

        # ptl should be able to remove users from all groups
        self.msu.deleteUserFromProjectGroups(config.USER_2, pname,
                                             config.USER_3)
        # user3 shouldn't exist in any group
        self.assertFalse(
            self.gu.member_in_group(config.USER_3, '%s-ptl' % pname))
        self.assertFalse(
            self.gu.member_in_group(config.USER_3, '%s-core' % pname))
        # Redmine part
        self.assertFalse(
            self.rm.check_user_role(pname, config.USER_3, 'Manager'))
        self.assertFalse(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))

    def test_core_manage_project_members(self):
        """ Test core can add and delete users to core group
        """
        # let admin create the project
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        groups = 'core-group'

        # Add user2 as core user
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname,
                                        config.USER_2, groups)
        # Test if user2 exists in core group
        self.assertTrue(
            self.gu.member_in_group(config.USER_2, '%s-core' % pname))
        # Redmine part
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_2, 'Developer'))

        groups = 'core-group'
        # core should be ale to add users to only core group and not ptl group
        # so user2 should be able to add user3 to only core group and not
        # ptl group
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3,
                                        groups)
        # user3 should exist in core group
        self.assertTrue(
            self.gu.member_in_group(config.USER_3, '%s-core' % pname))
        # Redmine part
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))

        groups = 'ptl-group'
        # core should not be allowed to add users to ptl group
        # so user2 should not be able to add user3 to ptl group
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3,
                                        groups)
        # user3 shouldn't exist in ptl group
        self.assertFalse(
            self.gu.member_in_group(config.USER_3, '%s-ptl' % pname))
        # Redmine part
        self.assertFalse(
            self.rm.check_user_role(pname, config.USER_3, 'Manager'))

        # core should be able to remove users from core group
        group = 'core-group'
        self.msu.deleteUserFromProjectGroups(config.USER_2, pname,
                                             config.USER_3, group)
        # user3 shouldn't exist in core group
        self.assertFalse(
            self.gu.member_in_group(config.USER_3, '%s-core' % pname))
        # Redmine part
        self.assertFalse(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))

    def test_non_member_manage_project_members(self):
        """ Test non project members can add and delete users to core group
        """
        # Let admin create the project
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))

        # non project meber can't add user to core group
        # user2 can't add user3 to core group
        groups = 'core-group'
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3,
                                        groups)
        # user3 shouldn't exist in core group
        self.assertFalse(
            self.gu.member_in_group(config.USER_3, '%s-core' % pname))
        # Redmine part
        self.assertFalse(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))

        groups = 'ptl-group'
        # non project meber can't add usr to ptl group
        # user2 can't add user3 to ptl group
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3,
                                        groups)
        # user3 shouldn't exist in ptl group
        self.assertFalse(
            self.gu.member_in_group(config.USER_3, '%s-ptl' % pname))
        # Redmine part
        self.assertFalse(
            self.rm.check_user_role(pname, config.USER_3, 'Manager'))

        # non project meber can't delete usr from any group.
        # Let admin add user3 to ptl and core groups,
        # then try to remove user3 from ptl and core groups by
        # user2 (i.e non member user)
        groups = 'ptl-group core-group'
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname,
                                        config.USER_3, groups)
        # non-admin user(user2) can't remove users from project groups
        self.msu.deleteUserFromProjectGroups(config.USER_2, pname,
                                             config.USER_3)
        # user3 should exist in ptl and core group
        self.assertTrue(
            self.gu.member_in_group(config.USER_3, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.USER_3, '%s-core' % pname))
        # Redmine part
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_3, 'Manager'))
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))

    def test_manage_project_members_for_dev_group(self):
        """ Add and Delete users from dev group by admin, ptl, core,
            dev and non members
        """
        pname = 'p_%s' % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.ADMIN_USER, options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        self.assertTrue(self.gu.group_exists('%s-dev' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-dev' % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(
            self.rm.check_user_role(pname, config.ADMIN_USER, 'Developer'))

        # Admin should add user to dev group
        groups = 'dev-group'
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname,
                                        config.USER_3, groups)
        # Test if user3 exists in dev group
        self.assertTrue(
            self.gu.member_in_group(config.USER_3, '%s-dev' % pname))
        # Redmine part
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))

        # admin should be able to remove users from dev group
        self.msu.deleteUserFromProjectGroups(config.ADMIN_USER, pname,
                                             config.USER_3)
        # user3 shouldn't exist in dev group
        self.assertFalse(
            self.gu.member_in_group(config.USER_3, '%s-dev' % pname))
        # Redmine part
        self.assertFalse(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))

        # ptl should add user to dev group
        # let admin add user2 as ptl
        groups = 'ptl-group'
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname,
                                        config.USER_2, groups)
        groups = 'dev-group'
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3,
                                        groups)
        # Test if user3 exists in dev group
        self.assertTrue(
            self.gu.member_in_group(config.USER_3, '%s-dev' % pname))
        # Redmine part
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))

        # ptl should be able to remove users from dev group
        self.msu.deleteUserFromProjectGroups(config.USER_2, pname,
                                             config.USER_3)
        # user3 shouldn't exist in dev group
        self.assertFalse(
            self.gu.member_in_group(config.USER_3, '%s-dev' % pname))
        # Redmine part
        self.assertFalse(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))
        # Remove user2 as ptl
        self.msu.deleteUserFromProjectGroups(config.ADMIN_USER, pname,
                                             config.USER_2)

        # core should add user to dev group
        # let admin add user2 as core
        groups = 'core-group'
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname,
                                        config.USER_2, groups)
        groups = 'dev-group'
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3,
                                        groups)
        # Test if user3 exists in dev group
        self.assertTrue(
            self.gu.member_in_group(config.USER_3, '%s-dev' % pname))
        # Redmine part
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))

        # core should be able to remove users from dev group
        group = 'dev-group'
        self.msu.deleteUserFromProjectGroups(config.USER_2, pname,
                                             config.USER_3, group)
        # user3 shouldn't exist in dev group
        self.assertFalse(
            self.gu.member_in_group(config.USER_3, '%s-dev' % pname))
        # Redmine part
        self.assertFalse(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))
        # Remove user2 as core
        self.msu.deleteUserFromProjectGroups(config.ADMIN_USER, pname,
                                             config.USER_2)

        # let admin add user2 as developer
        groups = 'dev-group'
        self.msu.addUsertoProjectGroups(config.ADMIN_USER, pname,
                                        config.USER_2, groups)
        # dev user should be able to add a new user to dev group
        groups = 'dev-group'
        self.msu.addUsertoProjectGroups(config.USER_2, pname, config.USER_3,
                                        groups)
        # Test if user3 exists in dev group
        self.assertTrue(
            self.gu.member_in_group(config.USER_3, '%s-dev' % pname))
        # Redmine part
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))

        # developer should be able to remove users from dev group
        group = 'dev-group'
        self.msu.deleteUserFromProjectGroups(config.USER_2, pname,
                                             config.USER_3, group)
        # user3 shouldn't exist in dev group
        self.assertFalse(
            self.gu.member_in_group(config.USER_3, '%s-dev' % pname))
        # Redmine part
        self.assertFalse(
            self.rm.check_user_role(pname, config.USER_3, 'Developer'))
        # Remove user2 ifrom dev group
        self.msu.deleteUserFromProjectGroups(config.ADMIN_USER, pname,
                                             config.USER_2)
Beispiel #21
0
class SFchecker:
    """ This checker is only intended for testin
    SF backup/restore and update. It checks that the user
    data defined in resourses.yaml are present on the SF.

    Those data must have been provisioned by SFProvisioner.
    """
    def __init__(self):
        with open("%s/resources.yaml" % pwd, 'r') as rsc:
            self.resources = yaml.load(rsc)
        config.USERS[config.ADMIN_USER]['auth_cookie'] = get_cookie(
            config.ADMIN_USER, config.USERS[config.ADMIN_USER]['password'])
        self.gu = GerritUtils(
            'http://%s/' % config.GATEWAY_HOST,
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
        self.ggu = GerritGitUtils(config.ADMIN_USER,
                                  config.ADMIN_PRIV_KEY_PATH,
                                  config.USERS[config.ADMIN_USER]['email'])
        self.ju = JenkinsUtils()
        self.rm = RedmineUtils(
            config.GATEWAY_URL + "/redmine/",
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])

    def check_project(self, name):
        print " Check project %s exists ..." % name,
        if not self.gu.project_exists(name) or \
           (is_present('SFRedmine') and not self.rm.project_exists(name)):
            print "FAIL"
            exit(1)
        print "OK"

    def check_files_in_project(self, name, files):
        print " Check files(%s) exists in project ..." % ",".join(files),
        # TODO(fbo); use gateway host instead of gerrit host
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, name)
        clone_dir = self.ggu.clone(url, name, config_review=False)
        for f in files:
            if not os.path.isfile(os.path.join(clone_dir, f)):
                print "FAIL"
                exit(1)

    def check_issues_on_project(self, name, issues):
        print " Check that at least %s issues exists for that project ...," %\
            len(issues)
        current_issues = self.rm.get_issues_by_project(name)
        if len(current_issues) < len(issues):
            print "FAIL: expected %s, project has %s" % (
                len(issues), len(current_issues))
            exit(1)
        print "OK"

    def check_jenkins_jobs(self, name, jobnames):
        print " Check that jenkins jobs(%s) exists ..." % ",".join(jobnames),
        for jobname in jobnames:
            if not '%s_%s' % (name, jobname) in self.ju.list_jobs():
                print "FAIL"
                exit(1)
        print "OK"

    def check_reviews_on_project(self, name, issues):
        reviews = [i for i in issues if i['review']]
        print " Check that at least %s reviews exists for that project ..." %\
            len(reviews),
        pending_reviews = self.ggu.list_open_reviews(name, config.GATEWAY_HOST)
        if not len(pending_reviews) >= len(reviews):
            print "FAIL"
            exit(1)
        print "OK"

    def check_pads(self, amount):
        pass

    def check_pasties(self, amount):
        pass

    def command(self, cmd):
        return ssh_run_cmd(os.path.expanduser("~/.ssh/id_rsa"),
                           "root",
                           config.GATEWAY_HOST, shlex.split(cmd))

    def compute_checksum(self, f):
        out = self.command("md5sum %s" % f)[0]
        if out:
            return out.split()[0]

    def read_file(self, f):
        return self.command("cat %s" % f)[0]

    def simple_login(self, user, password):
        """log as user"""
        return get_cookie(user, password)

    def check_users_list(self):
        print "Check that users are listable ...",
        users = [u['name'] for u in self.resources['users']]
        c = {'auth_pubtkt': config.USERS[config.ADMIN_USER]['auth_cookie']}
        url = 'http://%s/manage/project/membership/' % config.GATEWAY_HOST
        registered = requests.get(url,
                                  cookies=c).json()
        # usernames are in first position
        r_users = [u[0] for u in registered]
        if not set(users).issubset(set(r_users)):
            print "FAIL"
            exit(1)
        print "OK"

    def check_checksums(self):
        print "Check that expected file are there"
        checksum_list = yaml.load(file('/tmp/pc_checksums.yaml'))
        mismatch = False
        for f, checksum in checksum_list.items():
            c = self.compute_checksum(f)
            if c == checksum:
                print "Expected checksum (%s) for %s is OK." % (
                    checksum, f)
            else:
                print "Expected checksum (%s) for %s is WRONG (%s)." % (
                    checksum, f, c)
                print "New file is:"
                print "    %s" % self.read_file(f).replace("\n", "\n    ")
                mismatch = True
        if "checksum_warn_only" not in sys.argv and mismatch:
            sys.exit(1)

    def checker(self):
        self.check_checksums()
        self.check_users_list()
        for project in self.resources['projects']:
            print "Check user datas for %s" % project['name']
            self.check_project(project['name'])
            self.check_files_in_project(project['name'],
                                        [f['name'] for f in project['files']])
            if is_present('SFRedmine'):
                self.check_issues_on_project(project['name'],
                                             project['issues'])
            self.check_reviews_on_project(project['name'], project['issues'])
            self.check_jenkins_jobs(project['name'],
                                    [j['name'] for j in project['jobnames']])
        self.check_pads(2)
        self.check_pasties(2)
        for user in self.resources['local_users']:
            print "Check user %s can log in ..." % user['username'],
            if self.simple_login(user['username'],
                                 user['password']):
                print "OK"
            else:
                print "FAIL"
                exit(1)
class TestManageSF(Base):
    """ Functional tests that validate managesf features.
    Here we do basic verifications about project creation
    with managesf.
    """
    @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.rm = RedmineUtils(
            config.REDMINE_URL,
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
        self.gu = GerritUtils(
            'https://%s/' % config.GATEWAY_HOST,
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])

    def project_exists_ex(self, name, user):
        # Test here the project is "public"
        # ( Redmine API project detail does not return the private/public flag)
        rm = RedmineUtils(
            config.REDMINE_URL,
            auth_cookie=config.USERS[user]['auth_cookie'])
        try:
            return rm.project_exists(name)
        except Exception:
            return False

    def tearDown(self):
        for name in self.projects:
            self.msu.deleteProject(name,
                                   config.ADMIN_USER)
        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_create_public_project_as_admin(self):
        """ Create public project on redmine and gerrit as admin
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-core' % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(
            self.rm.check_user_role(pname, config.ADMIN_USER, 'Manager'))
        self.assertTrue(
            self.rm.check_user_role(pname, config.ADMIN_USER, 'Developer'))
        self.assertTrue(self.project_exists_ex(pname, config.USER_2))

    def test_create_private_project_as_admin(self):
        """ Create private project on redmine and gerrit as admin
        """
        pname = 'p_%s' % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.ADMIN_USER,
                            options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        self.assertTrue(self.gu.group_exists('%s-dev' % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-core' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-dev' % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(
            self.rm.check_user_role(pname, config.ADMIN_USER, 'Manager'))
        self.assertTrue(
            self.rm.check_user_role(pname, config.ADMIN_USER, 'Developer'))
        self.assertFalse(self.project_exists_ex(pname, config.USER_2))

    def test_delete_public_project_as_admin(self):
        """ Delete public project on redmine and gerrit as admin
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.rm.project_exists(pname))
        self.msu.deleteProject(pname, config.ADMIN_USER)
        self.assertFalse(self.gu.project_exists(pname))
        self.assertFalse(self.gu.group_exists('%s-ptl' % pname))
        self.assertFalse(self.rm.project_exists(pname))
        self.assertFalse(self.gu.group_exists('%s-core' % pname))
        self.projects.remove(pname)

    def test_create_public_project_as_user(self):
        """ Create public project on redmine and gerrit as user
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.USER_2)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-core' % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(self.project_exists_ex(pname, config.USER_2))
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_2, 'Manager'))
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_2, 'Developer'))
        self.assertTrue(self.project_exists_ex(pname, config.USER_3))

    def test_create_private_project_as_user(self):
        """ Create private project on redmine and gerrit as user
        """
        pname = 'p_%s' % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.USER_2,
                            options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        self.assertTrue(self.gu.group_exists('%s-dev' % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.USER_2, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.USER_2, '%s-core' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.USER_2, '%s-dev' % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(self.project_exists_ex(pname, config.USER_2))
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_2, 'Manager'))
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_2, 'Developer'))
        self.assertFalse(self.project_exists_ex(pname, config.USER_3))

    def test_create_public_project_with_users_in_group(self):
        """ Create public project on redmine and gerrit with users in groups
        """
        pname = 'p_%s' % create_random_str()
        u2mail = config.USERS[config.USER_2]['email']
        u3mail = config.USERS[config.USER_3]['email']
        options = {"ptl-group": "",
                   "core-group": "%s,%s" % (u2mail, u3mail),
                   }
        self.create_project(pname, config.ADMIN_USER,
                            options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        for user in (config.ADMIN_USER, config.USER_2, config.USER_3):
            self.assertTrue(self.gu.member_in_group(user, '%s-core' % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(
            self.rm.check_user_role(pname, config.ADMIN_USER, 'Manager'))
        for user in (config.ADMIN_USER, config.USER_2, config.USER_3):
            self.assertTrue(self.rm.check_user_role(pname, user, 'Developer'))

    def test_create_private_project_with_users_in_group(self):
        """ Create private project on redmine and gerrit with users in groups
        """
        pname = 'p_%s' % create_random_str()
        u2mail = config.USERS[config.USER_2]['email']
        u3mail = config.USERS[config.USER_3]['email']
        u4mail = config.USERS[config.USER_4]['email']
        options = {"private": "",
                   "ptl-group": "",
                   "core-group": "%s,%s" % (u2mail, u3mail),
                   "dev-group": "%s" % u4mail,
                   }
        self.create_project(pname, config.ADMIN_USER,
                            options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        for user in (config.ADMIN_USER, config.USER_2, config.USER_3):
            self.assertTrue(self.gu.member_in_group(user, '%s-core' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.USER_4, '%s-dev' % pname))
        # Redmine part
        # it should be visible to admin
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(
            self.rm.check_user_role(pname, config.ADMIN_USER, 'Manager'))
        for user in (config.ADMIN_USER, config.USER_2,
                     config.USER_3, config.USER_4):
            self.assertTrue(self.rm.check_user_role(pname, user, 'Developer'))

    def test_create_public_project_as_admin_clone_as_admin(self):
        """ Clone public project as admin and check content
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        ggu = GerritGitUtils(config.ADMIN_USER,
                             config.ADMIN_PRIV_KEY_PATH,
                             config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname)
        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')))
        # Verify meta/config branch own both group and ACLs config file
        ggu.fetch_meta_config(clone_dir)
        self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                    'project.config')))
        self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                    'groups')))
        # There is no group dev for a public project
        content = file(os.path.join(clone_dir, 'project.config')).read()
        self.assertFalse('%s-dev' % pname in content)
        content = file(os.path.join(clone_dir, 'groups')).read()
        self.assertFalse('%s-dev' % pname in content)

    def test_create_private_project_as_admin_clone_as_admin(self):
        """ Clone private project as admin and check content
        """
        pname = 'p_%s' % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.ADMIN_USER, options=options)
        ggu = GerritGitUtils(config.ADMIN_USER,
                             config.ADMIN_PRIV_KEY_PATH,
                             config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname)
        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')))
        # Verify meta/config branch own both group and ACLs config file
        ggu.fetch_meta_config(clone_dir)
        self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                    'project.config')))
        self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                    'groups')))
        # There is a group dev for a private project
        content = file(os.path.join(clone_dir, 'project.config')).read()
        self.assertTrue('%s-dev' % pname in content)
        content = file(os.path.join(clone_dir, 'groups')).read()
        self.assertTrue('%s-dev' % pname in content)

    def test_create_public_project_as_admin_clone_as_user(self):
        """ Create public project as admin then clone as user
        """
        pname = 'p_%s' % create_random_str()
        # create the project as admin
        self.create_project(pname, config.ADMIN_USER)
        # 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 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 test_upstream(self):
        """ Validate upstream feature of managesf
        """
        # Create a test upstream project
        pname_us = 'p_upstream'
        self.create_project(pname_us, config.ADMIN_USER)

        ggu_us = GerritGitUtils(config.ADMIN_USER,
                                config.ADMIN_PRIV_KEY_PATH,
                                config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname_us)
        # clone
        us_clone_dir = ggu_us.clone(url, pname_us)
        self.dirs_to_delete.append(os.path.dirname(us_clone_dir))
        # Test that the clone is a success
        self.assertTrue(os.path.isdir(us_clone_dir))
        # push some test files to the upstream project
        us_files = [str(x) for x in range(1, 10)]
        for f in us_files:
            file(os.path.join(us_clone_dir, f), 'w').write(f)
            os.chmod(os.path.join(us_clone_dir, f), 0755)

        ggu_us.add_commit_in_branch(us_clone_dir, "master",
                                    commit="Adding files 1-10",
                                    files=us_files)
        ggu_us.direct_push_branch(us_clone_dir, "master")

        # No create a test project with upstream pointing to the above
        upstream_url = "ssh://%s@%s:29418/%s" % (
            config.ADMIN_USER, config.GATEWAY_HOST, pname_us)
        pname = 'p_%s' % create_random_str()
        # create the project as admin
        options = {"upstream": upstream_url}
        self.create_project(pname, config.ADMIN_USER, options=options)

        ggu = GerritGitUtils(config.ADMIN_USER,
                             config.ADMIN_PRIV_KEY_PATH,
                             config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname)
        # clone
        clone_dir = ggu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))

        # Check if the files pushed in upstream project is present
        files = [f for f in os.listdir(clone_dir) if not f.startswith('.')]
        self.assertEqual(set(files), set(us_files))

    def test_delete_project_as_admin(self):
        """ Checking if admin can delete projects that are not owned by admin
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.USER_2)
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.rm.project_exists(pname))
        self.msu.deleteProject(pname, config.ADMIN_USER)
        self.assertFalse(self.gu.project_exists(pname))
        self.assertFalse(self.gu.group_exists('%s-ptl' % pname))
        self.assertFalse(self.rm.project_exists(pname))
        self.assertFalse(self.gu.group_exists('%s-core' % pname))
        self.projects.remove(pname)

    def test_list_active_members(self):
        """ Check the list of members as a list of tuples of emails and names
        """
        self.assertTrue(self.msu.list_active_members(config.USER_2))
class SFProvisioner(object):
    """ This provider is only intended for testing
    SF backup/restore and update. It provisions some
    user datas in a SF installation based on a resourses.yaml
    file. Later those data can be checked by its friend
    the SFChecker.

    Provisioned data should remain really simple.
    """
    def __init__(self):
        with open('resources.yaml', 'r') as rsc:
            self.resources = yaml.load(rsc)
        config.USERS[config.ADMIN_USER]['auth_cookie'] = get_cookie(
            config.ADMIN_USER, config.USERS[config.ADMIN_USER]['password'])
        self.msu = ManageSfUtils(config.GATEWAY_URL)
        self.ggu = GerritGitUtils(config.ADMIN_USER,
                                  config.ADMIN_PRIV_KEY_PATH,
                                  config.USERS[config.ADMIN_USER]['email'])
        self.ju = JenkinsUtils()
        self.rm = RedmineUtils(
            config.REDMINE_URL,
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])

    def create_project(self, name):
        print " Creating project %s ..." % name
        self.msu.createProject(name, config.ADMIN_USER)

    def push_files_in_project(self, name, files):
        print " Add files(%s) in a commit ..." % ",".join(files)
        # TODO(fbo); use gateway host instead of gerrit host
        self.url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                             config.GATEWAY_HOST, name)
        clone_dir = self.ggu.clone(self.url, name, config_review=False)
        self.clone_dir = clone_dir
        for f in files:
            file(os.path.join(clone_dir, f), 'w').write('data')
            self.ggu.git_add(clone_dir, (f,))
        self.ggu.add_commit_for_all_new_additions(clone_dir)
        self.ggu.direct_push_branch(clone_dir, 'master')

    def create_issues_on_project(self, name, issues):
        print " Create %s issue(s) for that project ..." % len(issues)
        for i in issues:
            issue = self.rm.create_issue(name, i['name'])
            yield issue, i['review']

    def create_jenkins_jobs(self, name, jobnames):
        print " Create Jenkins jobs(%s)  ..." % ",".join(jobnames)
        for jobname in jobnames:
            self.ju.create_job("%s_%s" % (name, jobname))

    def create_pads(self, amount):
        # TODO
        pass

    def create_pasties(self, amount):
        # TODO
        pass

    def create_review(self, project, issue):
        """Very basic review creator for statistics and restore tests
        purposes."""
        self.ggu.config_review(self.clone_dir)
        self.ggu.add_commit_in_branch(self.clone_dir,
                                      'branch_' + issue,
                                      commit='test\n\nBug: %s' % issue)
        self.ggu.review_push_branch(self.clone_dir, 'branch_' + issue)

    def provision(self):
        for project in self.resources['projects']:
            print "Create user datas for %s" % project['name']
            self.create_project(project['name'])
            self.push_files_in_project(project['name'],
                                       [f['name'] for f in project['files']])
            for i, review in self.create_issues_on_project(project['name'],
                                                           project['issues']):
                if review:
                    print "Create review for bug %i in %s" % (i,
                                                              project['name'])
                    self.create_review(project['name'], str(i))
            self.create_jenkins_jobs(project['name'],
                                     [j['name'] for j in project['jobnames']])
        self.create_pads(2)
        self.create_pasties(2)
Beispiel #24
0
class GerritHook(object):
    """Base for gerrit hooks"""

    def __init__(self, cli_options=None, conf_file=None):
        self.command_line_options = cli_options or DEFAULT_CLI_OPTIONS
        self.conf_file = conf_file
        self.config = yaml.load(conf_file)
        self.redmine_client = RedmineUtils(self.config['redmine_url'],
                                           key=self.config['redmine_key'])
        bottom_url = "/r/gitweb?p=%(project)s;a=commit;h=%(commit)s"
        self.gitweb_url = urllib_parse.urljoin(self.config['gitweb_url'],
                                               bottom_url)

    def get_parser(self):
        parser = argparse.ArgumentParser()
        for arg in self.command_line_options:
            parser.add_argument('--%s' % arg)
        return parser

    def get_trimmed_commit(self, commit):
        # We remove the fourth first lines of the commit message
        # tree, parent, author, committer and we just keep
        # the real user message
        commit_msg = subprocess.check_output(['git', 'cat-file',
                                              '-p', commit])
        return "\n".join(commit_msg.splitlines()[4:])

    def get_issue(self, commit, regexp):
        # GIT_SSH env var is setup by Gerrit when calling the hook
        commit_msg = subprocess.check_output(['git', 'cat-file',
                                              '-p', commit])
        return parse_commit_message(commit_msg, regexp)

    def main(self, args):
        error_code = 0
        commit_msg = self.get_trimmed_commit(args.commit)
        # Build message for the issue
        gitweb = self.gitweb_url % {'project': args.project + '.git',
                                    'commit': args.commit}
        message = self.msg % {'branch': args.branch,
                              'url': args.change_url,
                              'submitter': getattr(args, 'submitter', ''),
                              'commit': commit_msg,
                              'gitweb': gitweb}
        closing_issue = self.get_issue(args.commit, CLOSING_ISSUE)
        related_issue = self.get_issue(args.commit, RELATED_ISSUE)
        if closing_issue:
            if not self.redmine_client.set_issue_status(closing_issue,
                                                        self.status_closing,
                                                        message=message):
                msg = "Could not close issue #%s" % closing_issue
                logger.error(msg)
                error_code = 1
        if related_issue and related_issue != closing_issue:
            if not self.redmine_client.set_issue_status(related_issue,
                                                        self.status_related,
                                                        message=message):
                msg = "Could not update issue #%s" % closing_issue
                logger.error(msg)
                error_code = 1
        if not related_issue and not closing_issue:
            logger.debug("No issue mentioned, nothing to do.")
        return error_code
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 TestManageSF(Base):
    """ Functional tests that validate managesf features.
    Here we do basic verifications about project creation
    with managesf.
    """

    @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.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[config.ADMIN_USER]["auth_cookie"])

    def project_exists_ex(self, name, user):
        # Test here the project is "public"
        # ( Redmine API project detail does not return the private/public flag)
        rm = RedmineUtils(config.GATEWAY_URL + "/redmine/", auth_cookie=config.USERS[user]["auth_cookie"])
        try:
            return rm.project_exists(name)
        except Exception:
            return False

    def tearDown(self):
        for name in self.projects:
            self.msu.deleteProject(name, config.ADMIN_USER)
        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_create_public_project_as_admin(self):
        """ Create public project on redmine and gerrit as admin
        """
        pname = "p_%s" % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists("%s-ptl" % pname))
        self.assertTrue(self.gu.group_exists("%s-core" % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(self.gu.member_in_group(config.ADMIN_USER, "%s-ptl" % pname))
        self.assertTrue(self.gu.member_in_group(config.ADMIN_USER, "%s-core" % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(self.rm.check_user_role(pname, config.ADMIN_USER, "Manager"))
        self.assertTrue(self.rm.check_user_role(pname, config.ADMIN_USER, "Developer"))
        self.assertTrue(self.project_exists_ex(pname, config.USER_2))

    def test_create_private_project_as_admin(self):
        """ Create private project on redmine and gerrit as admin
        """
        pname = "p_%s" % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.ADMIN_USER, options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists("%s-ptl" % pname))
        self.assertTrue(self.gu.group_exists("%s-core" % pname))
        self.assertTrue(self.gu.group_exists("%s-dev" % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(self.gu.member_in_group(config.ADMIN_USER, "%s-ptl" % pname))
        self.assertTrue(self.gu.member_in_group(config.ADMIN_USER, "%s-core" % pname))
        self.assertTrue(self.gu.member_in_group(config.ADMIN_USER, "%s-dev" % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(self.rm.check_user_role(pname, config.ADMIN_USER, "Manager"))
        self.assertTrue(self.rm.check_user_role(pname, config.ADMIN_USER, "Developer"))
        self.assertFalse(self.project_exists_ex(pname, config.USER_2))

    def test_delete_public_project_as_admin(self):
        """ Delete public project on redmine and gerrit as admin
        """
        pname = "p_%s" % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.rm.project_exists(pname))
        self.msu.deleteProject(pname, config.ADMIN_USER)
        self.assertFalse(self.gu.project_exists(pname))
        self.assertFalse(self.gu.group_exists("%s-ptl" % pname))
        self.assertFalse(self.rm.project_exists(pname))
        self.assertFalse(self.gu.group_exists("%s-core" % pname))
        self.projects.remove(pname)

    def test_create_public_project_as_user(self):
        """ Create public project on redmine and gerrit as user
        """
        pname = "p_%s" % create_random_str()
        self.create_project(pname, config.USER_2)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists("%s-ptl" % pname))
        self.assertTrue(self.gu.group_exists("%s-core" % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(self.gu.member_in_group(config.ADMIN_USER, "%s-ptl" % pname))
        self.assertTrue(self.gu.member_in_group(config.ADMIN_USER, "%s-core" % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(self.project_exists_ex(pname, config.USER_2))
        self.assertTrue(self.rm.check_user_role(pname, config.USER_2, "Manager"))
        self.assertTrue(self.rm.check_user_role(pname, config.USER_2, "Developer"))
        self.assertTrue(self.project_exists_ex(pname, config.USER_3))

    def test_create_private_project_as_user(self):
        """ Create private project on redmine and gerrit as user
        """
        pname = "p_%s" % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.USER_2, options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists("%s-ptl" % pname))
        self.assertTrue(self.gu.group_exists("%s-core" % pname))
        self.assertTrue(self.gu.group_exists("%s-dev" % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(self.gu.member_in_group(config.USER_2, "%s-ptl" % pname))
        self.assertTrue(self.gu.member_in_group(config.USER_2, "%s-core" % pname))
        self.assertTrue(self.gu.member_in_group(config.USER_2, "%s-dev" % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(self.project_exists_ex(pname, config.USER_2))
        self.assertTrue(self.rm.check_user_role(pname, config.USER_2, "Manager"))
        self.assertTrue(self.rm.check_user_role(pname, config.USER_2, "Developer"))
        self.assertFalse(self.project_exists_ex(pname, config.USER_3))

    def test_create_public_project_with_users_in_group(self):
        """ Create public project on redmine and gerrit with users in groups
        """
        pname = "p_%s" % create_random_str()
        u2mail = config.USERS[config.USER_2]["email"]
        u3mail = config.USERS[config.USER_3]["email"]
        options = {"ptl-group": "", "core-group": "%s,%s" % (u2mail, u3mail)}
        self.create_project(pname, config.ADMIN_USER, options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(self.gu.member_in_group(config.ADMIN_USER, "%s-ptl" % pname))
        for user in (config.ADMIN_USER, config.USER_2, config.USER_3):
            self.assertTrue(self.gu.member_in_group(user, "%s-core" % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(self.rm.check_user_role(pname, config.ADMIN_USER, "Manager"))
        for user in (config.ADMIN_USER, config.USER_2, config.USER_3):
            self.assertTrue(self.rm.check_user_role(pname, user, "Developer"))

    def test_create_private_project_with_users_in_group(self):
        """ Create private project on redmine and gerrit with users in groups
        """
        pname = "p_%s" % create_random_str()
        u2mail = config.USERS[config.USER_2]["email"]
        u3mail = config.USERS[config.USER_3]["email"]
        u4mail = config.USERS[config.USER_4]["email"]
        options = {"private": "", "ptl-group": "", "core-group": "%s,%s" % (u2mail, u3mail), "dev-group": "%s" % u4mail}
        self.create_project(pname, config.ADMIN_USER, options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(self.gu.member_in_group(config.ADMIN_USER, "%s-ptl" % pname))
        for user in (config.ADMIN_USER, config.USER_2, config.USER_3):
            self.assertTrue(self.gu.member_in_group(user, "%s-core" % pname))
        self.assertTrue(self.gu.member_in_group(config.USER_4, "%s-dev" % pname))
        # Redmine part
        # it should be visible to admin
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(self.rm.check_user_role(pname, config.ADMIN_USER, "Manager"))
        for user in (config.ADMIN_USER, config.USER_2, config.USER_3, config.USER_4):
            self.assertTrue(self.rm.check_user_role(pname, user, "Developer"))

    def test_create_public_project_as_admin_clone_as_admin(self):
        """ Clone public project as admin and check content
        """
        pname = "p_%s" % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        ggu = GerritGitUtils(config.ADMIN_USER, config.ADMIN_PRIV_KEY_PATH, config.USERS[config.ADMIN_USER]["email"])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER, config.GATEWAY_HOST, pname)
        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")))
        # Verify meta/config branch own both group and ACLs config file
        ggu.fetch_meta_config(clone_dir)
        self.assertTrue(os.path.isfile(os.path.join(clone_dir, "project.config")))
        self.assertTrue(os.path.isfile(os.path.join(clone_dir, "groups")))
        # There is no group dev for a public project
        content = file(os.path.join(clone_dir, "project.config")).read()
        self.assertFalse("%s-dev" % pname in content)
        content = file(os.path.join(clone_dir, "groups")).read()
        self.assertFalse("%s-dev" % pname in content)

    def test_create_private_project_as_admin_clone_as_admin(self):
        """ Clone private project as admin and check content
        """
        pname = "p_%s" % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.ADMIN_USER, options=options)
        ggu = GerritGitUtils(config.ADMIN_USER, config.ADMIN_PRIV_KEY_PATH, config.USERS[config.ADMIN_USER]["email"])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER, config.GATEWAY_HOST, pname)
        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")))
        # Verify meta/config branch own both group and ACLs config file
        ggu.fetch_meta_config(clone_dir)
        self.assertTrue(os.path.isfile(os.path.join(clone_dir, "project.config")))
        self.assertTrue(os.path.isfile(os.path.join(clone_dir, "groups")))
        # There is a group dev for a private project
        content = file(os.path.join(clone_dir, "project.config")).read()
        self.assertTrue("%s-dev" % pname in content)
        content = file(os.path.join(clone_dir, "groups")).read()
        self.assertTrue("%s-dev" % pname in content)

    def test_create_public_project_as_admin_clone_as_user(self):
        """ Create public project as admin then clone as user
        """
        pname = "p_%s" % create_random_str()
        # create the project as admin
        self.create_project(pname, config.ADMIN_USER)
        # 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(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_upstream(self):
        """ Validate upstream feature of managesf
        """
        # Create a test upstream project
        pname_us = "p_upstream"
        self.create_project(pname_us, config.ADMIN_USER)

        ggu_us = GerritGitUtils(config.ADMIN_USER, config.ADMIN_PRIV_KEY_PATH, config.USERS[config.ADMIN_USER]["email"])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER, config.GATEWAY_HOST, pname_us)
        # clone
        us_clone_dir = ggu_us.clone(url, pname_us)
        self.dirs_to_delete.append(os.path.dirname(us_clone_dir))
        # Test that the clone is a success
        self.assertTrue(os.path.isdir(us_clone_dir))
        # push some test files to the upstream project
        us_files = [str(x) for x in range(1, 10)]
        for f in us_files:
            file(os.path.join(us_clone_dir, f), "w").write(f)
            os.chmod(os.path.join(us_clone_dir, f), 0755)

        ggu_us.add_commit_in_branch(us_clone_dir, "master", commit="Adding files 1-10", files=us_files)
        ggu_us.direct_push_branch(us_clone_dir, "master")

        # No create a test project with upstream pointing to the above
        upstream_url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER, config.GATEWAY_HOST, pname_us)
        pname = "p_%s" % create_random_str()
        # create the project as admin
        options = {"upstream": upstream_url, "upstream-ssh-key": config.ADMIN_PRIV_KEY_PATH}
        self.create_project(pname, config.ADMIN_USER, options=options)

        ggu = GerritGitUtils(config.ADMIN_USER, config.ADMIN_PRIV_KEY_PATH, config.USERS[config.ADMIN_USER]["email"])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER, config.GATEWAY_HOST, pname)
        # clone
        clone_dir = ggu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))

        # Check if the files pushed in upstream project is present
        files = [f for f in os.listdir(clone_dir) if not f.startswith(".")]
        self.assertEqual(set(files), set(us_files))

    def test_delete_project_as_admin(self):
        """ Check if admin can delete projects that are not owned by admin
        """
        pname = "p_%s" % create_random_str()
        self.create_project(pname, config.USER_2)
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.rm.project_exists(pname))
        self.msu.deleteProject(pname, config.ADMIN_USER)
        self.assertFalse(self.gu.project_exists(pname))
        self.assertFalse(self.gu.group_exists("%s-ptl" % pname))
        self.assertFalse(self.rm.project_exists(pname))
        self.assertFalse(self.gu.group_exists("%s-core" % pname))
        self.projects.remove(pname)

    def test_list_active_members(self):
        """ Check the list of members as a list of tuples of emails and names
        """
        self.assertTrue(self.msu.list_active_members(config.USER_2))

    def test_init_user_tests(self):
        """ Check if a test init feature behave as expected
        """
        project = "p_%s" % create_random_str()
        self.create_project(project, config.USER_4)
        self.msu.create_init_tests(project, config.USER_4)
        ggu = GerritGitUtils(config.ADMIN_USER, config.ADMIN_PRIV_KEY_PATH, config.USERS[config.ADMIN_USER]["email"])
        open_reviews = ggu.list_open_reviews("config", config.GATEWAY_HOST)
        match = [
            True
            for review in open_reviews
            if review["commitMessage"].startswith(
                "%s proposes initial test " "definition for project %s" % (config.USER_4, project)
            )
        ]
        self.assertEqual(len(match), 1)
        open_reviews = ggu.list_open_reviews(project, config.GATEWAY_HOST)
        match = [
            True
            for review in open_reviews
            if review["commitMessage"].startswith(
                "%s proposes initial test " "scripts for project %s" % (config.USER_4, project)
            )
        ]
        self.assertEqual(len(match), 1)

    def test_rest_urls_accessible(self):
        """ Check if managesf URLs are all working
        """
        project = "p_%s" % create_random_str()
        self.create_project(project, config.ADMIN_USER)
        cookies = dict(auth_pubtkt=config.USERS[config.ADMIN_USER]["auth_cookie"])
        paths = ["/manage/project/", "/manage/project/%s" % project, "/manage/project/membership/"]
        for path in paths:
            url = "http://%s%s" % (config.GATEWAY_HOST, path)
            resp = requests.get(url, cookies=cookies)
            self.assertEqual(200, resp.status_code)

    def test_validate_get_all_project_details(self):
        """ Check if managesf allow us to fetch projects details
        """
        project = "p_%s" % create_random_str()
        self.create_project(project, config.USER_2)
        admin_cookies = dict(auth_pubtkt=config.USERS[config.ADMIN_USER]["auth_cookie"])
        user2_cookies = dict(auth_pubtkt=config.USERS[config.USER_2]["auth_cookie"])
        url = "http://%s%s" % (config.GATEWAY_HOST, "/manage/project/")
        resp = requests.get(url, cookies=admin_cookies)
        self.assertEqual(200, resp.status_code)
        self.assertTrue(project in resp.json())
        self.assertTrue("config" in resp.json())
        resp = requests.get(url, cookies=user2_cookies)
        self.assertEqual(200, resp.status_code)
        self.assertTrue(project in resp.json())
        self.assertTrue("config" in resp.json())
        resp = requests.get(url, cookies=user2_cookies)
class TestManageSF(Base):
    """ Functional tests that validate managesf features.
    Here we do basic verifications about project creation
    with managesf.
    """
    @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.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[config.ADMIN_USER]['auth_cookie'])

    def project_exists_ex(self, name, user):
        # Test here the project is "public"
        # ( Redmine API project detail does not return the private/public flag)
        rm = RedmineUtils(
            config.GATEWAY_URL + "/redmine/",
            auth_cookie=config.USERS[user]['auth_cookie'])
        try:
            return rm.project_exists(name)
        except Exception:
            return False

    def tearDown(self):
        for name in self.projects:
            self.msu.deleteProject(name,
                                   config.ADMIN_USER)
        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_create_public_project_as_admin(self):
        """ Create public project on redmine and gerrit as admin
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-core' % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(
            self.rm.check_user_role(pname, config.ADMIN_USER, 'Manager'))
        self.assertTrue(
            self.rm.check_user_role(pname, config.ADMIN_USER, 'Developer'))
        self.assertTrue(self.project_exists_ex(pname, config.USER_2))

    def test_create_private_project_as_admin(self):
        """ Create private project on redmine and gerrit as admin
        """
        pname = 'p_%s' % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.ADMIN_USER,
                            options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        self.assertTrue(self.gu.group_exists('%s-dev' % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-core' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-dev' % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(
            self.rm.check_user_role(pname, config.ADMIN_USER, 'Manager'))
        self.assertTrue(
            self.rm.check_user_role(pname, config.ADMIN_USER, 'Developer'))
        self.assertFalse(self.project_exists_ex(pname, config.USER_2))

    def test_delete_public_project_as_admin(self):
        """ Delete public project on redmine and gerrit as admin
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.rm.project_exists(pname))
        self.msu.deleteProject(pname, config.ADMIN_USER)
        self.assertFalse(self.gu.project_exists(pname))
        self.assertFalse(self.gu.group_exists('%s-ptl' % pname))
        self.assertFalse(self.rm.project_exists(pname))
        self.assertFalse(self.gu.group_exists('%s-core' % pname))
        self.projects.remove(pname)

    def test_create_public_project_as_user(self):
        """ Create public project on redmine and gerrit as user
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.USER_2)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-core' % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(self.project_exists_ex(pname, config.USER_2))
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_2, 'Manager'))
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_2, 'Developer'))
        self.assertTrue(self.project_exists_ex(pname, config.USER_3))

    def test_create_private_project_as_user(self):
        """ Create private project on redmine and gerrit as user
        """
        pname = 'p_%s' % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.USER_2,
                            options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.gu.group_exists('%s-ptl' % pname))
        self.assertTrue(self.gu.group_exists('%s-core' % pname))
        self.assertTrue(self.gu.group_exists('%s-dev' % pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.USER_2, '%s-ptl' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.USER_2, '%s-core' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.USER_2, '%s-dev' % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(self.project_exists_ex(pname, config.USER_2))
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_2, 'Manager'))
        self.assertTrue(
            self.rm.check_user_role(pname, config.USER_2, 'Developer'))
        self.assertFalse(self.project_exists_ex(pname, config.USER_3))

    def test_create_public_project_with_users_in_group(self):
        """ Create public project on redmine and gerrit with users in groups
        """
        pname = 'p_%s' % create_random_str()
        u2mail = config.USERS[config.USER_2]['email']
        u3mail = config.USERS[config.USER_3]['email']
        options = {"ptl-group": "",
                   "core-group": "%s,%s" % (u2mail, u3mail),
                   }
        self.create_project(pname, config.ADMIN_USER,
                            options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        for user in (config.ADMIN_USER, config.USER_2, config.USER_3):
            self.assertTrue(self.gu.member_in_group(user, '%s-core' % pname))
        # Redmine part
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(
            self.rm.check_user_role(pname, config.ADMIN_USER, 'Manager'))
        for user in (config.ADMIN_USER, config.USER_2, config.USER_3):
            self.assertTrue(self.rm.check_user_role(pname, user, 'Developer'))

    def test_create_private_project_with_users_in_group(self):
        """ Create private project on redmine and gerrit with users in groups
        """
        pname = 'p_%s' % create_random_str()
        u2mail = config.USERS[config.USER_2]['email']
        u3mail = config.USERS[config.USER_3]['email']
        u4mail = config.USERS[config.USER_4]['email']
        options = {"private": "",
                   "ptl-group": "",
                   "core-group": "%s,%s" % (u2mail, u3mail),
                   "dev-group": "%s" % u4mail,
                   }
        self.create_project(pname, config.ADMIN_USER,
                            options=options)
        # Gerrit part
        self.assertTrue(self.gu.project_exists(pname))
        # TODO(Project creator, as project owner, should only be in ptl group)
        self.assertTrue(
            self.gu.member_in_group(config.ADMIN_USER, '%s-ptl' % pname))
        for user in (config.ADMIN_USER, config.USER_2, config.USER_3):
            self.assertTrue(self.gu.member_in_group(user, '%s-core' % pname))
        self.assertTrue(
            self.gu.member_in_group(config.USER_4, '%s-dev' % pname))
        # Redmine part
        # it should be visible to admin
        self.assertTrue(self.rm.project_exists(pname))
        self.assertTrue(
            self.rm.check_user_role(pname, config.ADMIN_USER, 'Manager'))
        for user in (config.ADMIN_USER, config.USER_2,
                     config.USER_3, config.USER_4):
            self.assertTrue(self.rm.check_user_role(pname, user, 'Developer'))

    def test_create_public_project_as_admin_clone_as_admin(self):
        """ Clone public project as admin and check content
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.ADMIN_USER)
        ggu = GerritGitUtils(config.ADMIN_USER,
                             config.ADMIN_PRIV_KEY_PATH,
                             config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname)
        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')))
        # Verify meta/config branch own both group and ACLs config file
        ggu.fetch_meta_config(clone_dir)
        self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                    'project.config')))
        self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                    'groups')))
        # There is no group dev for a public project
        content = file(os.path.join(clone_dir, 'project.config')).read()
        self.assertFalse('%s-dev' % pname in content)
        content = file(os.path.join(clone_dir, 'groups')).read()
        self.assertFalse('%s-dev' % pname in content)

    def test_create_private_project_as_admin_clone_as_admin(self):
        """ Clone private project as admin and check content
        """
        pname = 'p_%s' % create_random_str()
        options = {"private": ""}
        self.create_project(pname, config.ADMIN_USER, options=options)
        ggu = GerritGitUtils(config.ADMIN_USER,
                             config.ADMIN_PRIV_KEY_PATH,
                             config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname)
        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')))
        # Verify meta/config branch own both group and ACLs config file
        ggu.fetch_meta_config(clone_dir)
        self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                    'project.config')))
        self.assertTrue(os.path.isfile(os.path.join(clone_dir,
                                                    'groups')))
        # There is a group dev for a private project
        content = file(os.path.join(clone_dir, 'project.config')).read()
        self.assertTrue('%s-dev' % pname in content)
        content = file(os.path.join(clone_dir, 'groups')).read()
        self.assertTrue('%s-dev' % pname in content)

    def test_create_public_project_as_admin_clone_as_user(self):
        """ Create public project as admin then clone as user
        """
        pname = 'p_%s' % create_random_str()
        # create the project as admin
        self.create_project(pname, config.ADMIN_USER)
        # 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(
            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_upstream(self):
        """ Validate upstream feature of managesf
        """
        # Create a test upstream project
        pname_us = 'p_upstream'
        self.create_project(pname_us, config.ADMIN_USER)

        ggu_us = GerritGitUtils(config.ADMIN_USER,
                                config.ADMIN_PRIV_KEY_PATH,
                                config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname_us)
        # clone
        us_clone_dir = ggu_us.clone(url, pname_us)
        self.dirs_to_delete.append(os.path.dirname(us_clone_dir))
        # Test that the clone is a success
        self.assertTrue(os.path.isdir(us_clone_dir))
        # push some test files to the upstream project
        us_files = [str(x) for x in range(1, 10)]
        for f in us_files:
            file(os.path.join(us_clone_dir, f), 'w').write(f)
            os.chmod(os.path.join(us_clone_dir, f), 0755)

        ggu_us.add_commit_in_branch(us_clone_dir, "master",
                                    commit="Adding files 1-10",
                                    files=us_files)
        ggu_us.direct_push_branch(us_clone_dir, "master")

        # No create a test project with upstream pointing to the above
        upstream_url = "ssh://%s@%s:29418/%s" % (
            config.ADMIN_USER, config.GATEWAY_HOST, pname_us)
        pname = 'p_%s' % create_random_str()
        # create the project as admin
        options = {"upstream": upstream_url,
                   "upstream-ssh-key": config.ADMIN_PRIV_KEY_PATH}
        self.create_project(pname, config.ADMIN_USER, options=options)

        ggu = GerritGitUtils(config.ADMIN_USER,
                             config.ADMIN_PRIV_KEY_PATH,
                             config.USERS[config.ADMIN_USER]['email'])
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, pname)
        # clone
        clone_dir = ggu.clone(url, pname)
        self.dirs_to_delete.append(os.path.dirname(clone_dir))

        # Check if the files pushed in upstream project is present
        files = [f for f in os.listdir(clone_dir) if not f.startswith('.')]
        self.assertEqual(set(files), set(us_files))

    def test_delete_project_as_admin(self):
        """ Check if admin can delete projects that are not owned by admin
        """
        pname = 'p_%s' % create_random_str()
        self.create_project(pname, config.USER_2)
        self.assertTrue(self.gu.project_exists(pname))
        self.assertTrue(self.rm.project_exists(pname))
        self.msu.deleteProject(pname, config.ADMIN_USER)
        self.assertFalse(self.gu.project_exists(pname))
        self.assertFalse(self.gu.group_exists('%s-ptl' % pname))
        self.assertFalse(self.rm.project_exists(pname))
        self.assertFalse(self.gu.group_exists('%s-core' % pname))
        self.projects.remove(pname)

    def test_list_active_members(self):
        """ Check the list of members as a list of tuples of emails and names
        """
        self.assertTrue(self.msu.list_active_members(config.USER_2))

    def test_init_user_tests(self):
        """ Check if a test init feature behave as expected
        """
        project = 'p_%s' % create_random_str()
        self.create_project(project, config.USER_4)
        self.msu.create_init_tests(project, config.USER_4)
        ggu = GerritGitUtils(config.ADMIN_USER,
                             config.ADMIN_PRIV_KEY_PATH,
                             config.USERS[config.ADMIN_USER]['email'])
        open_reviews = ggu.list_open_reviews('config', config.GATEWAY_HOST)
        match = [True for review in open_reviews if review['commitMessage'].
                 startswith("%s proposes initial test "
                            "definition for project %s" %
                            (config.USER_4, project))]
        self.assertEqual(len(match), 1)
        open_reviews = ggu.list_open_reviews(project, config.GATEWAY_HOST)
        match = [True for review in open_reviews if review['commitMessage'].
                 startswith("%s proposes initial test "
                            "scripts for project %s" %
                            (config.USER_4, project))]
        self.assertEqual(len(match), 1)

    def test_rest_urls_accessible(self):
        """ Check if managesf URLs are all working
        """
        project = 'p_%s' % create_random_str()
        self.create_project(project, config.ADMIN_USER)
        cookies = dict(
            auth_pubtkt=config.USERS[config.ADMIN_USER]['auth_cookie'])
        paths = [
            "/manage/project/",
            "/manage/project/%s" % project,
            "/manage/project/membership/"]
        for path in paths:
            url = "http://%s%s" % (config.GATEWAY_HOST, path)
            resp = requests.get(url, cookies=cookies)
            self.assertEqual(200, resp.status_code)

    def test_validate_get_all_project_details(self):
        """ Check if managesf allow us to fetch projects details
        """
        project = 'p_%s' % create_random_str()
        self.create_project(project, config.USER_2)
        admin_cookies = dict(
            auth_pubtkt=config.USERS[config.ADMIN_USER]['auth_cookie'])
        user2_cookies = dict(
            auth_pubtkt=config.USERS[config.USER_2]['auth_cookie'])
        url = "http://%s%s" % (config.GATEWAY_HOST, "/manage/project/")
        resp = requests.get(url, cookies=admin_cookies)
        self.assertEqual(200, resp.status_code)
        self.assertTrue(project in resp.json())
        self.assertTrue('config' in resp.json())
        resp = requests.get(url, cookies=user2_cookies)
        self.assertEqual(200, resp.status_code)
        self.assertTrue(project in resp.json())
        self.assertTrue('config' in resp.json())
        resp = requests.get(url, cookies=user2_cookies)
Beispiel #28
0
class SFchecker:
    """ This checker is only intended for testin
    SF backup/restore and update. It checks that the user
    data defined in resourses.yaml are present on the SF.

    Those data must have been provisioned by SFProvisioner.
    """
    def __init__(self):
        with open("%s/resources.yaml" % pwd, 'r') as rsc:
            self.resources = yaml.load(rsc)
        config.USERS[config.ADMIN_USER]['auth_cookie'] = get_cookie(
            config.ADMIN_USER, config.USERS[config.ADMIN_USER]['password'])
        self.gu = GerritUtils(
            'http://%s/' % config.GATEWAY_HOST,
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
        self.ggu = GerritGitUtils(config.ADMIN_USER,
                                  config.ADMIN_PRIV_KEY_PATH,
                                  config.USERS[config.ADMIN_USER]['email'])
        self.ju = JenkinsUtils()
        self.rm = RedmineUtils(
            config.GATEWAY_URL + "/redmine/",
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])

    def check_project(self, name):
        print " Check project %s exists ..." % name,
        if not self.gu.project_exists(name) or \
           (is_present('SFRedmine') and not self.rm.project_exists(name)):
            print "FAIL"
            exit(1)
        print "OK"

    def check_files_in_project(self, name, files):
        print " Check files(%s) exists in project ..." % ",".join(files),
        # TODO(fbo); use gateway host instead of gerrit host
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER, config.GATEWAY_HOST,
                                        name)
        clone_dir = self.ggu.clone(url, name, config_review=False)
        for f in files:
            if not os.path.isfile(os.path.join(clone_dir, f)):
                print "FAIL"
                exit(1)

    def check_issues_on_project(self, name, issues):
        print " Check that at least %s issues exists for that project ...," %\
            len(issues)
        current_issues = self.rm.get_issues_by_project(name)
        if len(current_issues) < len(issues):
            print "FAIL: expected %s, project has %s" % (len(issues),
                                                         len(current_issues))
            exit(1)
        print "OK"

    def check_jenkins_jobs(self, name, jobnames):
        print " Check that jenkins jobs(%s) exists ..." % ",".join(jobnames),
        for jobname in jobnames:
            if not '%s_%s' % (name, jobname) in self.ju.list_jobs():
                print "FAIL"
                exit(1)
        print "OK"

    def check_reviews_on_project(self, name, issues):
        reviews = [i for i in issues if i['review']]
        print " Check that at least %s reviews exists for that project ..." %\
            len(reviews),
        pending_reviews = self.ggu.list_open_reviews(name, config.GATEWAY_HOST)
        if not len(pending_reviews) >= len(reviews):
            print "FAIL"
            exit(1)
        print "OK"

    def check_pads(self, amount):
        pass

    def check_pasties(self, amount):
        pass

    def checker(self):
        for project in self.resources['projects']:
            print "Check user datas for %s" % project['name']
            self.check_project(project['name'])
            self.check_files_in_project(project['name'],
                                        [f['name'] for f in project['files']])
            if is_present('SFRedmine'):
                self.check_issues_on_project(project['name'],
                                             project['issues'])
            self.check_reviews_on_project(project['name'], project['issues'])
            self.check_jenkins_jobs(project['name'],
                                    [j['name'] for j in project['jobnames']])
        self.check_pads(2)
        self.check_pasties(2)
class SFchecker:
    """ This checker is only intended for testin
    SF backup/restore and update. It checks that the user
    data defined in resourses.yaml are present on the SF.

    Those data must have been provisioned by SFProvisioner.
    """
    def __init__(self):
        with open("%s/resources.yaml" % pwd, 'r') as rsc:
            self.resources = yaml.load(rsc)
        config.USERS[config.ADMIN_USER]['auth_cookie'] = get_cookie(
            config.ADMIN_USER, config.USERS[config.ADMIN_USER]['password'])
        self.gu = GerritUtils(
            'http://%s/' % config.GATEWAY_HOST,
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])
        self.ggu = GerritGitUtils(config.ADMIN_USER,
                                  config.ADMIN_PRIV_KEY_PATH,
                                  config.USERS[config.ADMIN_USER]['email'])
        self.ju = JenkinsUtils()
        self.rm = RedmineUtils(
            config.GATEWAY_URL + "/redmine/",
            auth_cookie=config.USERS[config.ADMIN_USER]['auth_cookie'])

    def check_project(self, name):
        print " Check project %s exists ..." % name,
        if not self.gu.project_exists(name) or \
           not self.rm.project_exists(name):
            print "FAIL"
            exit(1)
        print "OK"

    def check_files_in_project(self, name, files):
        print " Check files(%s) exists in project ..." % ",".join(files),
        # TODO(fbo); use gateway host instead of gerrit host
        url = "ssh://%s@%s:29418/%s" % (config.ADMIN_USER,
                                        config.GATEWAY_HOST, name)
        clone_dir = self.ggu.clone(url, name, config_review=False)
        for f in files:
            if not os.path.isfile(os.path.join(clone_dir, f)):
                print "FAIL"
                exit(1)

    def check_issues_on_project(self, name, issues):
        print " Check that at least %s issues exists for that project ...," %\
            len(issues)
        current_issues = self.rm.get_issues_by_project(name)
        if len(current_issues) < len(issues):
            print "FAIL: expected %s, project has %s" % (
                len(issues), len(current_issues))
            exit(1)
        print "OK"

    def check_jenkins_jobs(self, name, jobnames):
        print " Check that jenkins jobs(%s) exists ..." % ",".join(jobnames),
        for jobname in jobnames:
            if not '%s_%s' % (name, jobname) in self.ju.list_jobs():
                print "FAIL"
                exit(1)
        print "OK"

    def check_reviews_on_project(self, name, issues):
        reviews = [i for i in issues if i['review']]
        print " Check that at least %s reviews exists for that project ..." %\
            len(reviews),
        pending_reviews = self.ggu.list_open_reviews(name, config.GATEWAY_HOST)
        if not len(pending_reviews) >= len(reviews):
            print "FAIL"
            exit(1)
        print "OK"

    def check_pads(self, amount):
        pass

    def check_pasties(self, amount):
        pass

    def checker(self):
        for project in self.resources['projects']:
            print "Check user datas for %s" % project['name']
            self.check_project(project['name'])
            self.check_files_in_project(project['name'],
                                        [f['name'] for f in project['files']])
            self.check_issues_on_project(project['name'], project['issues'])
            self.check_reviews_on_project(project['name'], project['issues'])
            self.check_jenkins_jobs(project['name'],
                                    [j['name'] for j in project['jobnames']])
        self.check_pads(2)
        self.check_pasties(2)
Beispiel #30
0
class GerritHook(object):
    """Base for gerrit hooks"""
    def __init__(self, cli_options=None, conf_file=None):
        self.command_line_options = cli_options or DEFAULT_CLI_OPTIONS
        self.conf_file = conf_file
        self.config = yaml.load(conf_file)
        self.redmine_client = RedmineUtils(self.config['redmine_url'],
                                           key=self.config['redmine_key'])
        bottom_url = "/r/gitweb?p=%(project)s;a=commit;h=%(commit)s"
        self.gitweb_url = urllib_parse.urljoin(self.config['gitweb_url'],
                                               bottom_url)

    def get_parser(self):
        parser = argparse.ArgumentParser()
        for arg in self.command_line_options:
            parser.add_argument('--%s' % arg)
        return parser

    def get_trimmed_commit(self, commit):
        # We remove the fourth first lines of the commit message
        # tree, parent, author, committer and we just keep
        # the real user message
        commit_msg = subprocess.check_output(['git', 'cat-file', '-p', commit])
        return "\n".join(commit_msg.splitlines()[4:])

    def get_issue(self, commit, regexp):
        # GIT_SSH env var is setup by Gerrit when calling the hook
        commit_msg = subprocess.check_output(['git', 'cat-file', '-p', commit])
        return parse_commit_message(commit_msg, regexp)

    def main(self, args):
        error_code = 0
        commit_msg = self.get_trimmed_commit(args.commit)
        # Build message for the issue
        gitweb = self.gitweb_url % {
            'project': args.project + '.git',
            'commit': args.commit
        }
        message = self.msg % {
            'branch': args.branch,
            'url': args.change_url,
            'submitter': getattr(args, 'submitter', ''),
            'commit': commit_msg,
            'gitweb': gitweb
        }
        closing_issue = self.get_issue(args.commit, CLOSING_ISSUE)
        related_issue = self.get_issue(args.commit, RELATED_ISSUE)
        if closing_issue:
            if not self.redmine_client.set_issue_status(
                    closing_issue, self.status_closing, message=message):
                msg = "Could not close issue #%s" % closing_issue
                logger.error(msg)
                error_code = 1
        if related_issue and related_issue != closing_issue:
            if not self.redmine_client.set_issue_status(
                    related_issue, self.status_related, message=message):
                msg = "Could not update issue #%s" % closing_issue
                logger.error(msg)
                error_code = 1
        if not related_issue and not closing_issue:
            logger.debug("No issue mentioned, nothing to do.")
        return error_code