55import asyncio
66import logging
77import traceback
8+ from abc import ABC , abstractmethod
89from datetime import datetime , timedelta , timezone
910from typing import Optional , Union
1011
1819from validation .utils .trigger import Trigger
1920
2021
21- class Testcase :
22-
23- CHECK_TIME_FOR_REACTION = 60 * 5
24- CHECK_TIME_FOR_SUBMIT_BUILDS = 60 * 45
25- CHECK_TIME_FOR_BUILD = 60 * 20
26- CHECK_TIME_FOR_WATCH_STATUSES = 60 * 30
22+ class Testcase (ABC ):
23+ CHECK_TIME_FOR_REACTION = 5
24+ CHECK_TIME_FOR_SUBMIT_BUILDS = 45
25+ CHECK_TIME_FOR_BUILD = 20
26+ CHECK_TIME_FOR_WATCH_STATUSES = 30
2727
2828 def __init__ (
2929 self ,
@@ -46,21 +46,10 @@ def __init__(
4646 self ._build = None
4747 self ._statuses : list [GithubCheckRun ] | list [CommitFlag ] = []
4848
49- @property
50- def copr_project_name (self ):
51- """
52- Get the name of Copr project from id of the PR.
53- :return:
54- """
55- if self .pr and not self ._copr_project_name :
56- self ._copr_project_name = self .construct_copr_project_name ()
57- return self ._copr_project_name
58-
5949 async def run_test (self ):
6050 """
6151 Run all checks, if there is any failure message, send it to Sentry and in case of
6252 opening PR close it.
63- :return:
6453 """
6554 try :
6655 await self .run_checks ()
@@ -81,7 +70,6 @@ async def run_test(self):
8170 def trigger_build (self ):
8271 """
8372 Trigger the build (by commenting/pushing to the PR/opening a new PR).
84- :return:
8573 """
8674 logging .info (
8775 "Triggering a build for %s" ,
@@ -98,7 +86,6 @@ def trigger_build(self):
9886 def push_to_pr (self ):
9987 """
10088 Push a new commit to the PR.
101- :return:
10289 """
10390 branch = self .pr .source_branch
10491 commit_msg = f"Commit build trigger ({ datetime .now (tz = timezone .utc ).strftime ('%d/%m/%y' )} )"
@@ -108,7 +95,6 @@ def create_pr(self):
10895 """
10996 Create a new PR, if the source branch 'test_case_opened_pr' does not exist,
11097 create one and commit some changes before it.
111- :return:
11298 """
11399 source_branch = f"test/{ self .deployment .name } /opened_pr"
114100 pr_title = f"Basic test case ({ self .deployment .name } ): opened PR trigger"
@@ -133,7 +119,6 @@ def create_pr(self):
133119 async def run_checks (self ):
134120 """
135121 Run all checks of the test case.
136- :return:
137122 """
138123 await self .check_build_submitted ()
139124
@@ -148,14 +133,13 @@ async def check_pending_check_runs(self):
148133 """
149134 Check whether some check run is set to queued
150135 (they are updated in loop, so it is enough).
151- :return:
152136 """
153137 status_names = [self .get_status_name (status ) for status in self .get_statuses ()]
154138
155- watch_end = datetime .now (tz = timezone .utc ) + timedelta (seconds = self .CHECK_TIME_FOR_REACTION )
139+ watch_end = datetime .now (tz = timezone .utc ) + timedelta (minutes = self .CHECK_TIME_FOR_REACTION )
156140 failure_message = (
157141 "Github check runs were not set to queued in time "
158- "({self.CHECK_TIME_FOR_REACTION} minutes).\n "
142+ f "({ self .CHECK_TIME_FOR_REACTION } minutes).\n "
159143 )
160144
161145 # when a new PR is opened
@@ -193,7 +177,6 @@ async def check_pending_check_runs(self):
193177 async def check_build_submitted (self ):
194178 """
195179 Check whether the build was submitted in Copr in time.
196- :return:
197180 """
198181 if self .pr :
199182 try :
@@ -212,7 +195,7 @@ async def check_build_submitted(self):
212195 self .trigger_build ()
213196
214197 watch_end = datetime .now (tz = timezone .utc ) + timedelta (
215- seconds = self .CHECK_TIME_FOR_SUBMIT_BUILDS ,
198+ minutes = self .CHECK_TIME_FOR_SUBMIT_BUILDS ,
216199 )
217200
218201 await self .check_pending_check_runs ()
@@ -226,7 +209,7 @@ async def check_build_submitted(self):
226209 if datetime .now (tz = timezone .utc ) > watch_end :
227210 self .failure_msg += (
228211 "The build was not submitted in Copr in time "
229- "({self.CHECK_TIME_FOR_SUBMIT_BUILDS} minutes).\n "
212+ f "({ self .CHECK_TIME_FOR_SUBMIT_BUILDS } minutes).\n "
230213 )
231214 return
232215
@@ -262,10 +245,11 @@ async def check_build_submitted(self):
262245 async def check_build (self , build_id ):
263246 """
264247 Check whether the build was successful in Copr.
265- :param build_id: ID of the build
266- :return:
248+
249+ Args:
250+ build_id: ID of the Copr build
267251 """
268- watch_end = datetime .now (tz = timezone .utc ) + timedelta (seconds = self .CHECK_TIME_FOR_BUILD )
252+ watch_end = datetime .now (tz = timezone .utc ) + timedelta (minutes = self .CHECK_TIME_FOR_BUILD )
269253 state_reported = ""
270254 logging .info ("Watching Copr build %s" , build_id )
271255
@@ -301,7 +285,6 @@ async def check_build(self, build_id):
301285 def check_comment (self ):
302286 """
303287 Check whether p-s has commented when the Copr build was not successful.
304- :return:
305288 """
306289 failure = "The build in Copr was not successful." in self .failure_msg
307290
@@ -337,7 +320,6 @@ def fix_packit_yaml(self, branch: str):
337320 async def check_completed_statuses (self ):
338321 """
339322 Check whether all check runs are set to success.
340- :return:
341323 """
342324 if "The build in Copr was not successful." in self .failure_msg :
343325 return
@@ -351,12 +333,11 @@ async def check_completed_statuses(self):
351333
352334 async def watch_statuses (self ):
353335 """
354- Watch the check runs, if all the check runs have completed
355- status, return the check runs.
356- :return: list[CheckRun]
336+ Watch the check runs, if all the check runs have completed status,
337+ return.
357338 """
358339 watch_end = datetime .now (tz = timezone .utc ) + timedelta (
359- seconds = self .CHECK_TIME_FOR_WATCH_STATUSES ,
340+ minutes = self .CHECK_TIME_FOR_WATCH_STATUSES ,
360341 )
361342 logging .info (
362343 "Watching statuses for commit %s" ,
@@ -383,52 +364,62 @@ async def watch_statuses(self):
383364 await asyncio .sleep (60 )
384365
385366 @property
367+ @abstractmethod
386368 def account_name (self ):
387369 """
388- Get the name of the (bot) account in GitHub/GitLab.
370+ Name of the (bot) account in GitHub/GitLab.
389371 """
390- return
391372
373+ @property
374+ @abstractmethod
375+ def copr_project_name (self ):
376+ """
377+ Name of Copr project from id of the PR.
378+ """
379+
380+ @abstractmethod
392381 def get_statuses (self ) -> Union [list [GithubCheckRun ], list [CommitFlag ]]:
393382 """
394383 Get the statuses (checks in GitHub).
395384 """
396385
386+ @abstractmethod
397387 def is_status_completed (self , status : Union [GithubCheckRun , CommitFlag ]) -> bool :
398388 """
399389 Check whether the status is in completed state (e.g. success, failure).
400390 """
401391
392+ @abstractmethod
402393 def is_status_successful (self , status : Union [GithubCheckRun , CommitFlag ]) -> bool :
403394 """
404395 Check whether the status is in successful state.
405396 """
406397
398+ @abstractmethod
407399 def delete_previous_branch (self , ref : str ):
408400 """
409401 Delete the branch from the previous test run if it exists.
410402 """
411403
404+ @abstractmethod
412405 def create_file_in_new_branch (self , branch : str ):
413406 """
414407 Create a new branch and a new file in it via API (creates new commit).
415408 """
416409
410+ @abstractmethod
417411 def update_file_and_commit (self , path : str , commit_msg : str , content : str , branch : str ):
418412 """
419413 Update a file via API (creates new commit).
420414 """
421415
422- def construct_copr_project_name (self ) -> str :
423- """
424- Construct the Copr project name for the PR to check.
425- """
426-
416+ @abstractmethod
427417 def get_status_name (self , status : Union [GithubCheckRun , CommitFlag ]) -> str :
428418 """
429419 Get the name of the status/check that is visible to user.
430420 """
431421
422+ @abstractmethod
432423 def create_empty_commit (self , branch : str , commit_msg : str ) -> str :
433424 """
434425 Create an empty commit via API.
0 commit comments