benchmark 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #!/usr/bin/env python
  2. # isort: skip_file
  3. # flake8: noqa: S002
  4. """
  5. This script benchmarks the performance of issue owner assignment in Sentry.
  6. Usage: python benchmark_codeowners/benchmark <path_to_code_mapping_file> <path_to_event_data_file>
  7. """
  8. from sentry.runner import configure
  9. configure()
  10. import sys
  11. import random
  12. import string
  13. import time
  14. from sentry.models.organization import Organization
  15. from sentry.models.projectownership import ProjectOwnership
  16. from sentry.models.project import Project
  17. from sentry.models.team import Team
  18. from sentry.utils import json
  19. import sentry_sdk
  20. from sentry.models.projectteam import ProjectTeam
  21. # disable sentry as it creates lots of noise in the output
  22. sentry_sdk.init(None)
  23. def main(code_mapping_file, event_data_file):
  24. def get_code_mapping():
  25. with open(code_mapping_file) as f:
  26. return json.loads(f.read())
  27. def get_event_data():
  28. with open(event_data_file) as f:
  29. return json.loads(f.read())
  30. code_mapping = get_code_mapping()
  31. # create an organization
  32. org_id = random.randint(1, 1000000)
  33. org_name = "".join(random.choices(string.ascii_letters + string.digits, k=10))
  34. org_slug = "".join(random.choices(string.ascii_lowercase + string.digits, k=10))
  35. org, _ = Organization.objects.get_or_create(name=org_name, slug=org_slug, id=org_id)
  36. # create a project
  37. project_id = random.randint(1, 1000000)
  38. project_name = "".join(random.choices(string.ascii_letters + string.digits, k=10))
  39. project_slug = "".join(random.choices(string.ascii_lowercase + string.digits, k=10))
  40. project, _ = Project.objects.get_or_create(
  41. name=project_name, slug=project_slug, id=project_id, organization_id=org.id
  42. )
  43. # create teams for all actors
  44. teams_to_create = []
  45. seen_teams = set()
  46. for rule in code_mapping["rules"]:
  47. for owner in rule["owners"]:
  48. team_name = owner["identifier"]
  49. if team_name not in seen_teams:
  50. teams_to_create.append(
  51. Team(
  52. name=team_name,
  53. slug=team_name,
  54. organization_id=org.id,
  55. id=owner["id"],
  56. )
  57. )
  58. seen_teams.add(team_name)
  59. # delete teams from previous runs
  60. Team.objects.filter(id__in=[team.id for team in teams_to_create]).delete()
  61. Team.objects.bulk_create(teams_to_create)
  62. for team in Team.objects.filter(organization_id=org.id):
  63. ProjectTeam.objects.create(project_id=project.id, team_id=team.id)
  64. # create a projectownership
  65. ProjectOwnership.objects.get_or_create(
  66. project_id=project.id,
  67. schema=code_mapping,
  68. )
  69. event_data = get_event_data()
  70. start = time.time()
  71. issue_owners = ProjectOwnership.get_issue_owners(project.id, event_data)
  72. elapsed_time = time.time() - start
  73. print(f"Time taken: {elapsed_time:.6f} seconds") # noqa
  74. print("Ownership rules:")
  75. for rule, teams, rule_type in issue_owners:
  76. print(f"\nRule:")
  77. print(f" Type: {rule_type}")
  78. print(f" Pattern: {rule.matcher.pattern}")
  79. print(" Teams:")
  80. for team in teams: # type: ignore[assignment]
  81. if isinstance(team, Team): # Only handle Team objects
  82. print(f" - {team.name} (id: {team.id})")
  83. if __name__ == "__main__":
  84. if len(sys.argv) != 3:
  85. print( # noqa
  86. "Usage: python benchmark_codeowners/benchmark <path_to_code_mapping_file> <path_to_event_data_file>"
  87. )
  88. sys.exit(1)
  89. main(sys.argv[1], sys.argv[2])