benchmark_imports.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. """Runs the benchmarks and inserts the results into the database."""
  2. from __future__ import annotations
  3. import argparse
  4. import json
  5. import os
  6. from datetime import datetime
  7. import psycopg2
  8. def extract_stats_from_json(json_file: str) -> dict:
  9. """Extracts the stats from the JSON data and returns them as dictionaries.
  10. Args:
  11. json_file: The JSON file to extract the stats data from.
  12. Returns:
  13. dict: The stats for each test.
  14. """
  15. with open(json_file, "r") as file:
  16. json_data = json.load(file)
  17. # Load the JSON data if it is a string, otherwise assume it's already a dictionary
  18. data = json.loads(json_data) if isinstance(json_data, str) else json_data
  19. result = data.get("results", [{}])[0]
  20. return {
  21. k: v
  22. for k, v in result.items()
  23. if k in ("mean", "stddev", "median", "min", "max")
  24. }
  25. def insert_benchmarking_data(
  26. db_connection_url: str,
  27. os_type_version: str,
  28. python_version: str,
  29. performance_data: dict,
  30. commit_sha: str,
  31. pr_title: str,
  32. branch_name: str,
  33. event_type: str,
  34. actor: str,
  35. pr_id: str,
  36. ):
  37. """Insert the benchmarking data into the database.
  38. Args:
  39. db_connection_url: The URL to connect to the database.
  40. os_type_version: The OS type and version to insert.
  41. python_version: The Python version to insert.
  42. performance_data: The imports performance data to insert.
  43. commit_sha: The commit SHA to insert.
  44. pr_title: The PR title to insert.
  45. branch_name: The name of the branch.
  46. event_type: Type of github event(push, pull request, etc)
  47. actor: Username of the user that triggered the run.
  48. pr_id: Id of the PR.
  49. """
  50. # Serialize the JSON data
  51. simple_app_performance_json = json.dumps(performance_data)
  52. # Get the current timestamp
  53. current_timestamp = datetime.now()
  54. # Connect to the database and insert the data
  55. with psycopg2.connect(db_connection_url) as conn, conn.cursor() as cursor:
  56. insert_query = """
  57. INSERT INTO import_benchmarks (os, python_version, commit_sha, time, pr_title, branch_name, event_type, actor, performance, pr_id)
  58. VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s);
  59. """
  60. cursor.execute(
  61. insert_query,
  62. (
  63. os_type_version,
  64. python_version,
  65. commit_sha,
  66. current_timestamp,
  67. pr_title,
  68. branch_name,
  69. event_type,
  70. actor,
  71. simple_app_performance_json,
  72. pr_id,
  73. ),
  74. )
  75. # Commit the transaction
  76. conn.commit()
  77. def main():
  78. """Runs the benchmarks and inserts the results."""
  79. # Get the commit SHA and JSON directory from the command line arguments
  80. parser = argparse.ArgumentParser(description="Run benchmarks and process results.")
  81. parser.add_argument(
  82. "--os", help="The OS type and version to insert into the database."
  83. )
  84. parser.add_argument(
  85. "--python-version", help="The Python version to insert into the database."
  86. )
  87. parser.add_argument(
  88. "--commit-sha", help="The commit SHA to insert into the database."
  89. )
  90. parser.add_argument(
  91. "--benchmark-json",
  92. help="The JSON file containing the benchmark results.",
  93. )
  94. parser.add_argument(
  95. "--db-url",
  96. help="The URL to connect to the database.",
  97. required=True,
  98. )
  99. parser.add_argument(
  100. "--pr-title",
  101. help="The PR title to insert into the database.",
  102. )
  103. parser.add_argument(
  104. "--branch-name",
  105. help="The current branch",
  106. required=True,
  107. )
  108. parser.add_argument(
  109. "--event-type",
  110. help="The github event type",
  111. required=True,
  112. )
  113. parser.add_argument(
  114. "--actor",
  115. help="Username of the user that triggered the run.",
  116. required=True,
  117. )
  118. parser.add_argument(
  119. "--pr-id",
  120. help="ID of the PR.",
  121. required=True,
  122. )
  123. args = parser.parse_args()
  124. # Get the PR title from env or the args. For the PR merge or push event, there is no PR title, leaving it empty.
  125. pr_title = args.pr_title or os.getenv("PR_TITLE", "")
  126. cleaned_benchmark_results = extract_stats_from_json(args.benchmark_json)
  127. # Insert the data into the database
  128. insert_benchmarking_data(
  129. db_connection_url=args.db_url,
  130. os_type_version=args.os,
  131. python_version=args.python_version,
  132. performance_data=cleaned_benchmark_results,
  133. commit_sha=args.commit_sha,
  134. pr_title=pr_title,
  135. branch_name=args.branch_name,
  136. event_type=args.event_type,
  137. actor=args.actor,
  138. pr_id=args.pr_id,
  139. )
  140. if __name__ == "__main__":
  141. main()