312 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			312 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python
 | 
						|
# Copyright (C) 2016 The Android Open Source Project
 | 
						|
#
 | 
						|
# Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
# you may not use this file except in compliance with the License.
 | 
						|
# You may obtain a copy of the License at
 | 
						|
#
 | 
						|
# http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
#
 | 
						|
# Unless required by applicable law or agreed to in writing, software
 | 
						|
# distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
# See the License for the specific language governing permissions and
 | 
						|
# limitations under the License.
 | 
						|
 | 
						|
"""
 | 
						|
This script will populate an empty standard Gerrit instance with some
 | 
						|
data for local testing.
 | 
						|
 | 
						|
TODO(hiesel): Make real git commits instead of empty changes
 | 
						|
TODO(hiesel): Add comments
 | 
						|
"""
 | 
						|
 | 
						|
from __future__ import print_function
 | 
						|
import atexit
 | 
						|
import json
 | 
						|
import optparse
 | 
						|
import os
 | 
						|
import random
 | 
						|
import shutil
 | 
						|
import subprocess
 | 
						|
import tempfile
 | 
						|
import requests
 | 
						|
import requests.auth
 | 
						|
 | 
						|
DEFAULT_TMP_PATH = "/tmp"
 | 
						|
TMP_PATH = ""
 | 
						|
BASE_URL = "http://localhost:%d/a/"
 | 
						|
 | 
						|
ADMIN_BASIC_AUTH = requests.auth.HTTPBasicAuth("admin", "secret")
 | 
						|
 | 
						|
# GROUP_ADMIN stores a GroupInfo for the admin group (see Gerrit rest docs)
 | 
						|
# In addition, GROUP_ADMIN["name"] stores the admin group"s name.
 | 
						|
GROUP_ADMIN = {}
 | 
						|
 | 
						|
HEADERS = {"Content-Type": "application/json", "charset": "UTF-8"}
 | 
						|
 | 
						|
# Random names from US Census Data
 | 
						|
FIRST_NAMES = [
 | 
						|
    "Casey", "Yesenia", "Shirley", "Tara", "Wanda", "Sheryl", "Jaime",
 | 
						|
    "Elaine", "Charlotte", "Carly", "Bonnie", "Kirsten", "Kathryn", "Carla",
 | 
						|
    "Katrina", "Melody", "Suzanne", "Sandy", "Joann", "Kristie", "Sally",
 | 
						|
    "Emma", "Susan", "Amanda", "Alyssa", "Patty", "Angie", "Dominique",
 | 
						|
    "Cynthia", "Jennifer", "Theresa", "Desiree", "Kaylee", "Maureen",
 | 
						|
    "Jeanne", "Kellie", "Valerie", "Nina", "Judy", "Diamond", "Anita",
 | 
						|
    "Rebekah", "Stefanie", "Kendra", "Erin", "Tammie", "Tracey", "Bridget",
 | 
						|
    "Krystal", "Jasmin", "Sonia", "Meghan", "Rebecca", "Jeanette", "Meredith",
 | 
						|
    "Beverly", "Natasha", "Chloe", "Selena", "Teresa", "Sheena", "Cassandra",
 | 
						|
    "Rhonda", "Tami", "Jodi", "Shelly", "Angela", "Kimberly", "Terry",
 | 
						|
    "Joanna", "Isabella", "Lindsey", "Loretta", "Dana", "Veronica", "Carolyn",
 | 
						|
    "Laura", "Karen", "Dawn", "Alejandra", "Cassie", "Lorraine", "Yolanda",
 | 
						|
    "Kerry", "Stephanie", "Caitlin", "Melanie", "Kerri", "Doris", "Sandra",
 | 
						|
    "Beth", "Carol", "Vicki", "Shelia", "Bethany", "Rachael", "Donna",
 | 
						|
    "Alexandra", "Barbara", "Ana", "Jillian", "Ann", "Rachel", "Lauren",
 | 
						|
    "Hayley", "Misty", "Brianna", "Tanya", "Danielle", "Courtney",
 | 
						|
    "Jacqueline", "Becky", "Christy", "Alisha", "Phyllis", "Faith", "Jocelyn",
 | 
						|
    "Nancy", "Gloria", "Kristen", "Evelyn", "Julie", "Julia", "Kara",
 | 
						|
    "Chelsey", "Cassidy", "Jean", "Chelsea", "Jenny", "Diana", "Haley",
 | 
						|
    "Kristine", "Kristina", "Erika", "Jenna", "Alison", "Deanna", "Abigail",
 | 
						|
    "Melissa", "Sierra", "Linda", "Monica", "Tasha", "Traci", "Yvonne",
 | 
						|
    "Tracy", "Marie", "Maria", "Michaela", "Stacie", "April", "Morgan",
 | 
						|
    "Cathy", "Darlene", "Cristina", "Emily" "Ian", "Russell", "Phillip", "Jay",
 | 
						|
    "Barry", "Brad", "Frederick", "Fernando", "Timothy", "Ricardo", "Bernard",
 | 
						|
    "Daniel", "Ruben", "Alexis", "Kyle", "Malik", "Norman", "Kent", "Melvin",
 | 
						|
    "Stephen", "Daryl", "Kurt", "Greg", "Alex", "Mario", "Riley", "Marvin",
 | 
						|
    "Dan", "Steven", "Roberto", "Lucas", "Leroy", "Preston", "Drew", "Fred",
 | 
						|
    "Casey", "Wesley", "Elijah", "Reginald", "Joel", "Christopher", "Jacob",
 | 
						|
    "Luis", "Philip", "Mark", "Rickey", "Todd", "Scott", "Terrence", "Jim",
 | 
						|
    "Stanley", "Bobby", "Thomas", "Gabriel", "Tracy", "Marcus", "Peter",
 | 
						|
    "Michael", "Calvin", "Herbert", "Darryl", "Billy", "Ross", "Dustin",
 | 
						|
    "Jaime", "Adam", "Henry", "Xavier", "Dominic", "Lonnie", "Danny", "Victor",
 | 
						|
    "Glen", "Perry", "Jackson", "Grant", "Gerald", "Garrett", "Alejandro",
 | 
						|
    "Eddie", "Alan", "Ronnie", "Mathew", "Dave", "Wayne", "Joe", "Craig",
 | 
						|
    "Terry", "Chris", "Randall", "Parker", "Francis", "Keith", "Neil", "Caleb",
 | 
						|
    "Jon", "Earl", "Taylor", "Bryce", "Brady", "Max", "Sergio", "Leon", "Gene",
 | 
						|
    "Darin", "Bill", "Edgar", "Antonio", "Dalton", "Arthur", "Austin",
 | 
						|
    "Cristian", "Kevin", "Omar", "Kelly", "Aaron", "Ethan", "Tom", "Isaac",
 | 
						|
    "Maurice", "Gilbert", "Hunter", "Willie", "Harry", "Dale", "Darius",
 | 
						|
    "Jerome", "Jason", "Harold", "Kerry", "Clarence", "Gregg", "Shane",
 | 
						|
    "Eduardo", "Micheal", "Howard", "Vernon", "Rodney", "Anthony", "Levi",
 | 
						|
    "Larry", "Franklin", "Jimmy", "Jonathon", "Carl",
 | 
						|
]
 | 
						|
 | 
						|
LAST_NAMES = [
 | 
						|
    "Savage", "Hendrix", "Moon", "Larsen", "Rocha", "Burgess", "Bailey",
 | 
						|
    "Farley", "Moses", "Schmidt", "Brown", "Hoover", "Klein", "Jennings",
 | 
						|
    "Braun", "Rangel", "Casey", "Dougherty", "Hancock", "Wolf", "Henry",
 | 
						|
    "Thomas", "Bentley", "Barnett", "Kline", "Pitts", "Rojas", "Sosa", "Paul",
 | 
						|
    "Hess", "Chase", "Mckay", "Bender", "Colins", "Montoya", "Townsend",
 | 
						|
    "Potts", "Ayala", "Avery", "Sherman", "Tapia", "Hamilton", "Ferguson",
 | 
						|
    "Huang", "Hooper", "Zamora", "Logan", "Lloyd", "Quinn", "Monroe", "Brock",
 | 
						|
    "Ibarra", "Fowler", "Weiss", "Montgomery", "Diaz", "Dixon", "Olson",
 | 
						|
    "Robertson", "Arias", "Benjamin", "Abbott", "Stein", "Schroeder", "Beck",
 | 
						|
    "Velasquez", "Barber", "Nichols", "Ortiz", "Burns", "Moody", "Stokes",
 | 
						|
    "Wilcox", "Rush", "Michael", "Kidd", "Rowland", "Mclean", "Saunders",
 | 
						|
    "Chung", "Newton", "Potter", "Hickman", "Ray", "Larson", "Figueroa",
 | 
						|
    "Duncan", "Sparks", "Rose", "Hodge", "Huynh", "Joseph", "Morales",
 | 
						|
    "Beasley", "Mora", "Fry", "Ross", "Novak", "Hahn", "Wise", "Knight",
 | 
						|
    "Frederick", "Heath", "Pollard", "Vega", "Mcclain", "Buckley", "Conrad",
 | 
						|
    "Cantrell", "Bond", "Mejia", "Wang", "Lewis", "Johns", "Mcknight",
 | 
						|
    "Callahan", "Reynolds", "Norris", "Burnett", "Carey", "Jacobson", "Oneill",
 | 
						|
    "Oconnor", "Leonard", "Mckenzie", "Hale", "Delgado", "Spence", "Brandt",
 | 
						|
    "Obrien", "Bowman", "James", "Avila", "Roberts", "Barker", "Cohen",
 | 
						|
    "Bradley", "Prince", "Warren", "Summers", "Little", "Caldwell", "Garrett",
 | 
						|
    "Hughes", "Norton", "Burke", "Holden", "Merritt", "Lee", "Frank", "Wiley",
 | 
						|
    "Ho", "Weber", "Keith", "Winters", "Gray", "Watts", "Brady", "Aguilar",
 | 
						|
    "Nicholson", "David", "Pace", "Cervantes", "Davis", "Baxter", "Sanchez",
 | 
						|
    "Singleton", "Taylor", "Strickland", "Glenn", "Valentine", "Roy",
 | 
						|
    "Cameron", "Beard", "Norman", "Fritz", "Anthony", "Koch", "Parrish",
 | 
						|
    "Herman", "Hines", "Sutton", "Gallegos", "Stephenson", "Lozano",
 | 
						|
    "Franklin", "Howe", "Bauer", "Love", "Ali", "Ellison", "Lester", "Guzman",
 | 
						|
    "Jarvis", "Espinoza", "Fletcher", "Burton", "Woodard", "Peterson",
 | 
						|
    "Barajas", "Richard", "Bryan", "Goodman", "Cline", "Rowe", "Faulkner",
 | 
						|
    "Crawford", "Mueller", "Patterson", "Hull", "Walton", "Wu", "Flores",
 | 
						|
    "York", "Dickson", "Barnes", "Fisher", "Strong", "Juarez", "Fitzgerald",
 | 
						|
    "Schmitt", "Blevins", "Villa", "Sullivan", "Velazquez", "Horton",
 | 
						|
    "Meadows", "Riley", "Barrera", "Neal", "Mendez", "Mcdonald", "Floyd",
 | 
						|
    "Lynch", "Mcdowell", "Benson", "Hebert", "Livingston", "Davies",
 | 
						|
    "Richardson", "Vincent", "Davenport", "Osborn", "Mckee", "Marshall",
 | 
						|
    "Ferrell", "Martinez", "Melton", "Mercer", "Yoder", "Jacobs", "Mcdaniel",
 | 
						|
    "Mcmillan", "Peters", "Atkinson", "Wood", "Briggs", "Valencia", "Chandler",
 | 
						|
    "Rios", "Hunter", "Bean", "Hicks", "Hays", "Lucero", "Malone", "Waller",
 | 
						|
    "Banks", "Myers", "Mitchell", "Grimes", "Houston", "Hampton", "Trujillo",
 | 
						|
    "Perkins", "Moran", "Welch", "Contreras", "Montes", "Ayers", "Hayden",
 | 
						|
    "Daniel", "Weeks", "Porter", "Gill", "Mullen", "Nolan", "Dorsey", "Crane",
 | 
						|
    "Estes", "Lam", "Wells", "Cisneros", "Giles", "Watson", "Vang", "Scott",
 | 
						|
    "Knox", "Hanna", "Fields",
 | 
						|
]
 | 
						|
 | 
						|
 | 
						|
def clean(json_string):
 | 
						|
    # Strip JSON XSS Tag
 | 
						|
    json_string = json_string.strip()
 | 
						|
    if json_string.startswith(")]}'"):
 | 
						|
        return json_string[5:]
 | 
						|
    return json_string
 | 
						|
 | 
						|
 | 
						|
def basic_auth(user):
 | 
						|
    return requests.auth.HTTPBasicAuth(user["username"], user["http_password"])
 | 
						|
 | 
						|
 | 
						|
def fetch_admin_group():
 | 
						|
    global GROUP_ADMIN
 | 
						|
    # Get admin group
 | 
						|
    r = json.loads(clean(requests.get(
 | 
						|
        BASE_URL + "groups/?suggest=ad&p=All-Projects",
 | 
						|
        headers=HEADERS,
 | 
						|
        auth=ADMIN_BASIC_AUTH).text))
 | 
						|
    admin_group_name = r.keys()[0]
 | 
						|
    GROUP_ADMIN = r[admin_group_name]
 | 
						|
    GROUP_ADMIN["name"] = admin_group_name
 | 
						|
 | 
						|
 | 
						|
def generate_random_text():
 | 
						|
    return " ".join([random.choice("lorem ipsum "
 | 
						|
                                   "doleret delendam "
 | 
						|
                                   "\n esse".split(" ")) for _ in range(1,
 | 
						|
                                                                        100)])
 | 
						|
 | 
						|
 | 
						|
def set_up():
 | 
						|
    global TMP_PATH
 | 
						|
    TMP_PATH = tempfile.mkdtemp()
 | 
						|
    atexit.register(clean_up)
 | 
						|
    os.makedirs(TMP_PATH + "/ssh")
 | 
						|
    os.makedirs(TMP_PATH + "/repos")
 | 
						|
    fetch_admin_group()
 | 
						|
 | 
						|
 | 
						|
def get_random_users(num_users):
 | 
						|
    users = random.sample([(f, l) for f in FIRST_NAMES for l in LAST_NAMES],
 | 
						|
                          num_users)
 | 
						|
    names = []
 | 
						|
    for u in users:
 | 
						|
        names.append({"firstname": u[0],
 | 
						|
                      "lastname": u[1],
 | 
						|
                      "name": u[0] + " " + u[1],
 | 
						|
                      "username": u[0] + u[1],
 | 
						|
                      "email": u[0] + "." + u[1] + "@gerritcodereview.com",
 | 
						|
                      "http_password": "secret",
 | 
						|
                      "groups": []})
 | 
						|
    return names
 | 
						|
 | 
						|
 | 
						|
def generate_ssh_keys(gerrit_users):
 | 
						|
    for user in gerrit_users:
 | 
						|
        key_file = TMP_PATH + "/ssh/" + user["username"] + ".key"
 | 
						|
        subprocess.check_output(["ssh-keygen", "-f", key_file, "-N", ""])
 | 
						|
        with open(key_file + ".pub", "r") as f:
 | 
						|
            user["ssh_key"] = f.read()
 | 
						|
 | 
						|
 | 
						|
def create_gerrit_groups():
 | 
						|
    groups = [
 | 
						|
        {"name": "iOS-Maintainers", "description": "iOS Maintainers",
 | 
						|
         "visible_to_all": True, "owner": GROUP_ADMIN["name"],
 | 
						|
         "owner_id": GROUP_ADMIN["id"]},
 | 
						|
        {"name": "Android-Maintainers", "description": "Android Maintainers",
 | 
						|
         "visible_to_all": True, "owner": GROUP_ADMIN["name"],
 | 
						|
         "owner_id": GROUP_ADMIN["id"]},
 | 
						|
        {"name": "Backend-Maintainers", "description": "Backend Maintainers",
 | 
						|
         "visible_to_all": True, "owner": GROUP_ADMIN["name"],
 | 
						|
         "owner_id": GROUP_ADMIN["id"]},
 | 
						|
        {"name": "Script-Maintainers", "description": "Script Maintainers",
 | 
						|
         "visible_to_all": True, "owner": GROUP_ADMIN["name"],
 | 
						|
         "owner_id": GROUP_ADMIN["id"]},
 | 
						|
        {"name": "Security-Team", "description": "Sec Team",
 | 
						|
         "visible_to_all": False, "owner": GROUP_ADMIN["name"],
 | 
						|
         "owner_id": GROUP_ADMIN["id"]}]
 | 
						|
    for g in groups:
 | 
						|
        requests.put(BASE_URL + "groups/" + g["name"],
 | 
						|
                     json.dumps(g),
 | 
						|
                     headers=HEADERS,
 | 
						|
                     auth=ADMIN_BASIC_AUTH)
 | 
						|
    return [g["name"] for g in groups]
 | 
						|
 | 
						|
 | 
						|
def create_gerrit_projects(owner_groups):
 | 
						|
    projects = [
 | 
						|
        {"id": "android", "name": "Android", "parent": "All-Projects",
 | 
						|
         "branches": ["master"], "description": "Our android app.",
 | 
						|
         "owners": [owner_groups[0]], "create_empty_commit": True},
 | 
						|
        {"id": "ios", "name": "iOS", "parent": "All-Projects",
 | 
						|
         "branches": ["master"], "description": "Our ios app.",
 | 
						|
         "owners": [owner_groups[1]], "create_empty_commit": True},
 | 
						|
        {"id": "backend", "name": "Backend", "parent": "All-Projects",
 | 
						|
         "branches": ["master"], "description": "Our awesome backend.",
 | 
						|
         "owners": [owner_groups[2]], "create_empty_commit": True},
 | 
						|
        {"id": "scripts", "name": "Scripts", "parent": "All-Projects",
 | 
						|
         "branches": ["master"], "description": "some small scripts.",
 | 
						|
         "owners": [owner_groups[3]], "create_empty_commit": True}]
 | 
						|
    for p in projects:
 | 
						|
        requests.put(BASE_URL + "projects/" + p["name"],
 | 
						|
                     json.dumps(p),
 | 
						|
                     headers=HEADERS,
 | 
						|
                     auth=ADMIN_BASIC_AUTH)
 | 
						|
    return [p["name"] for p in projects]
 | 
						|
 | 
						|
 | 
						|
def create_gerrit_users(gerrit_users):
 | 
						|
    for user in gerrit_users:
 | 
						|
        requests.put(BASE_URL + "accounts/" + user["username"],
 | 
						|
                     json.dumps(user),
 | 
						|
                     headers=HEADERS,
 | 
						|
                     auth=ADMIN_BASIC_AUTH)
 | 
						|
 | 
						|
 | 
						|
def create_change(user, project_name):
 | 
						|
    random_commit_message = generate_random_text()
 | 
						|
    change = {
 | 
						|
        "project": project_name,
 | 
						|
        "subject": random_commit_message.split("\n")[0],
 | 
						|
        "branch": "master",
 | 
						|
        "status": "NEW",
 | 
						|
    }
 | 
						|
    requests.post(BASE_URL + "changes/",
 | 
						|
                  json.dumps(change),
 | 
						|
                  headers=HEADERS,
 | 
						|
                  auth=basic_auth(user))
 | 
						|
 | 
						|
 | 
						|
def clean_up():
 | 
						|
    shutil.rmtree(TMP_PATH)
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    p = optparse.OptionParser()
 | 
						|
    p.add_option("-u", "--user_count", action="store",
 | 
						|
                 default=100,
 | 
						|
                 type='int',
 | 
						|
                 help="number of users to generate")
 | 
						|
    p.add_option("-p", "--port", action="store",
 | 
						|
                 default=8080,
 | 
						|
                 type='int',
 | 
						|
                 help="port of server")
 | 
						|
    (options, _) = p.parse_args()
 | 
						|
    global BASE_URL
 | 
						|
    BASE_URL = BASE_URL % options.port
 | 
						|
    print(BASE_URL)
 | 
						|
 | 
						|
    set_up()
 | 
						|
    gerrit_users = get_random_users(options.user_count)
 | 
						|
 | 
						|
    group_names = create_gerrit_groups()
 | 
						|
    for idx, u in enumerate(gerrit_users):
 | 
						|
        u["groups"].append(group_names[idx % len(group_names)])
 | 
						|
        if idx % 5 == 0:
 | 
						|
            # Also add to security group
 | 
						|
            u["groups"].append(group_names[4])
 | 
						|
 | 
						|
    generate_ssh_keys(gerrit_users)
 | 
						|
    create_gerrit_users(gerrit_users)
 | 
						|
 | 
						|
    project_names = create_gerrit_projects(group_names)
 | 
						|
 | 
						|
    for idx, u in enumerate(gerrit_users):
 | 
						|
        for _ in xrange(random.randint(1, 5)):
 | 
						|
            create_change(u, project_names[4 * idx / len(gerrit_users)])
 | 
						|
 | 
						|
main()
 |