1111from optparse import OptionParser
1212from datetime import datetime
1313
14- __version__ = '2.60 .0'
14+ __version__ = '2.61 .0'
1515
1616FORMAT = "%(message)s"
1717logging .basicConfig (format = FORMAT )
@@ -417,7 +417,7 @@ def upload_test_file(self, project_id, filename):
417417 """
418418 def delete_project_parameters (self , project_id , parameter_id ):
419419 me = self .get_me ()
420- path = "/ users/%s/projects/%s/config/parameters/%s" % ( me ['id' ], project_id , parameter_id )
420+ path = "users/%s/projects/%s/config/parameters/%s" % ( me ['id' ], project_id , parameter_id )
421421 return self .delete (path = path )
422422
423423 """ Get project parameters
@@ -438,7 +438,7 @@ def upload_data_file(self, project_id, filename):
438438 def set_project_parameters (self , project_id , parameters ):
439439 #set key value pair for project. e.g. : {'key' : 'my_key', 'value':'my_value'}
440440 me = self .get_me ()
441- path = "/ users/%s/projects/%s/config/parameters" % ( me ['id' ], project_id )
441+ path = "users/%s/projects/%s/config/parameters" % ( me ['id' ], project_id )
442442 return self .post (path = path , payload = parameters )
443443
444444 """ Get project config
@@ -455,7 +455,7 @@ def set_project_config(self, project_id, payload):
455455 if isinstance (payload , str ):
456456 payload = json .loads (payload )
457457 me = self .get_me ()
458- path = "/ users/%s/projects/%s/config" % ( me ['id' ], project_id )
458+ path = "users/%s/projects/%s/config" % ( me ['id' ], project_id )
459459 return self .post (path = path , payload = payload )
460460
461461 """Set project framework based on a framework integer id
@@ -514,7 +514,7 @@ def start_test_run(self, project_id, device_group_id=None, device_model_ids=None
514514
515515 # actually start the test run
516516 me = self .get_me ()
517- path = "/ users/%s/projects/%s/runs" % (me ['id' ], project_id )
517+ path = "users/%s/projects/%s/runs" % (me ['id' ], project_id )
518518 test_run = self .post (path = path , payload = payload )
519519 print ("Test run id: %s" % test_run ['id' ])
520520 print ("Name: %s" % test_run ['displayName' ])
@@ -676,8 +676,6 @@ def get_jobs(self, limit=0):
676676 """
677677 def create_job (self , job_name , content , job_type = "BUILD" ):
678678 job = self .post (path = "me/jobs" , payload = {"name" : job_name , "content" : content , "type" : job_type })
679- print (job )
680-
681679 logger .info ("Job %s: %s (%s) created" % (job ['id' ], job ['name' ], job ['type' ] ))
682680 return job
683681
@@ -747,6 +745,34 @@ def download_build_output_files(self, job_id, build_id, results_folder="results"
747745 logger .info ("No files to download" )
748746 logger .info ("" )
749747
748+ """ Awaits completion of the given test run
749+ """
750+ def wait_build (self , job_id , build_id ):
751+ if job_id and build_id :
752+ print ("Awaiting completion of build with id {}. Will wait forever polling every {}." .format (
753+ build_id ,
754+ '{} minutes' .format (self .polling_interval_mins ) if self .polling_interval_mins != 1 else 'minute' ))
755+
756+ while True :
757+ time .sleep (self .polling_interval_mins * 6 )
758+ if not self .api_key :
759+ self .access_token = None
760+ self .get_token ()
761+ buildStatus = self .get_build (job_id , build_id )
762+ if buildStatus and 'state' in buildStatus :
763+ if buildStatus ['state' ] == "FINISHED" :
764+ print ("The build with id: %s has FINISHED with status: %s" % (build_id , buildStatus ['status' ]))
765+ break
766+ elif buildStatus ['state' ] == "CREATED" :
767+ print ("[%s] The build with id: %s is awaiting to be scheduled" % (time .strftime ("%H:%M:%S" ), build_id ))
768+ continue
769+ elif buildStatus ['state' ] == "BUILDING" :
770+ print ("[%s] The build with id: %s is running" % (time .strftime ("%H:%M:%S" ), build_id ))
771+ continue
772+
773+ print ("Couldn't establish the state of the build with id: %s. Aborting" % build_id )
774+ print (buildStatus )
775+ sys .exit (1 )
750776
751777 """ Downloads test run files to a directory hierarchy
752778 """
@@ -879,6 +905,18 @@ def format_epilog(self, formatter):
879905 Download test run screenshots. Screenshots will be downloaded to
880906 current directory in a structure:
881907 [test-run-id]/[device-run-id]-[device-name]/screenshots/...
908+ jobs Get list of your jobs
909+ builds <job-id> Get list of your builds
910+ create-job <job-name> <job-configuration> Create a new job. Job configuration in Jenkins pipeline format
911+ See the sample of Jenkisfile in http://docs.bitbar.com/build-service/guide.html
912+ update-job <job-id> <job-name> <job-configuration>
913+ Update existing job
914+ create-build <job-id> <build-configuration> Create a new build job. See https://cloud.testdroid.com/cloud/swagger-ui.html
915+ for details of build configuration
916+ delete-job <job-id> Delete job and all the builds in it
917+ delete-build <job-id> <build-id> Delete build by id
918+ download-builds-files <job-id> <build-id> Download all the results of the specific build
919+ wait-build <job-id> <build-id> Await completion (polling) of the build
882920
883921"""
884922 parser = MyParser (usage = usage , description = description , epilog = epilog , version = "%s %s" % ("%prog" , __version__ ))
@@ -929,7 +967,8 @@ def get_commands(self):
929967 "create-build" : self .create_build ,
930968 "delete-job" : self .delete_job ,
931969 "delete-build" : self .delete_build ,
932- "download-builds-files" : self .download_build_output_files
970+ "download-builds-files" : self .download_build_output_files ,
971+ "wait-build" : self .wait_build
933972
934973 }
935974 return commands
0 commit comments