Skip to content

Commit 76a7ec1

Browse files
author
Sakari Rautiainen
authored
Merge pull request #101 from bitbar/devel
Build API functions
2 parents 26e126e + 2abd265 commit 76a7ec1

File tree

2 files changed

+136
-3
lines changed

2 files changed

+136
-3
lines changed

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
2.60.0
2+
* Added Build API functions
13
2.43.0
24
* Add function for restarting test runs and device runs
35
* Travis builds

testdroid/__init__.py

Lines changed: 134 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111
from optparse import OptionParser
1212
from datetime import datetime
1313

14-
__version__ = '2.43.0'
14+
__version__ = '2.60.0'
1515

1616
FORMAT = "%(message)s"
1717
logging.basicConfig(format=FORMAT)
1818

1919
logger = logging.getLogger('testdroid')
2020
logger.setLevel(logging.INFO)
2121

22-
2322
class RequestTimeout(Exception):
2423

2524
def __init__(self, msg):
@@ -399,6 +398,14 @@ def upload_application_file(self, project_id, filename):
399398
path = "users/%s/projects/%s/files/application" % (me['id'], project_id)
400399
self.upload(path=path, filename=filename)
401400

401+
""" Upload application file to project
402+
"""
403+
def upload_file(self, filename):
404+
me = self.get_me()
405+
path = "users/%s/files" % (me['id'])
406+
res = self.upload(path=path, filename=filename).json()
407+
print("ID:%s Name:%s Size:%s" % (str(res['id']).ljust(10), res['name'].ljust(15), res['size']))
408+
402409
""" Upload test file to project
403410
"""
404411
def upload_test_file(self, project_id, filename):
@@ -627,6 +634,120 @@ def get_device_run_files(self, project_id, test_run_id, device_session_id, tags=
627634
def get_input_files(self, limit=0):
628635
return self.get("me/files?limit={}&filter=s_direction_eq_INPUT".format(limit))
629636

637+
""" Build API
638+
"""
639+
640+
""" Print projects
641+
"""
642+
def print_jobs(self, limit=0):
643+
for job in self.get_jobs(limit)['data']:
644+
print("%s %s \"%s\"" % (str(job['id']).ljust(10), job['name'].ljust(15), job['content']))
645+
646+
""" Print builds
647+
"""
648+
def print_builds(self, job_id, limit=0):
649+
print("id buildNumber state status duration")
650+
for build in self.get_builds(job_id, limit)['data']:
651+
print("%s %s %s %s %s" % (str(build['id']).ljust(12), str(build['buildNumber']).ljust(5), build['state'].ljust(10), build['status'].ljust(10), build['duration']))
652+
653+
654+
655+
""" Get builds from the job
656+
"""
657+
def get_builds(self, job_id, limit=0):
658+
return self.get("me/jobs/{}/builds?limit={}".format(job_id,limit))
659+
660+
""" Get job by id
661+
"""
662+
def get_job(self, job_id):
663+
return self.get("me/jobs/{}".format(job_id))
664+
665+
""" Get build from the job
666+
"""
667+
def get_build(self, job_id, build_id):
668+
return self.get("me/jobs/{}/builds/{}".format(job_id, build_id))
669+
670+
""" Get jobs
671+
"""
672+
def get_jobs(self, limit=0):
673+
return self.get("me/jobs?limit={}".format(limit))
674+
675+
""" Create a job
676+
"""
677+
def create_job(self, job_name, content, job_type="BUILD"):
678+
job = self.post(path="me/jobs", payload={"name": job_name, "content": content, "type": job_type})
679+
print(job)
680+
681+
logger.info("Job %s: %s (%s) created" % (job['id'], job['name'], job['type'] ))
682+
return job
683+
684+
""" Create a build
685+
build_config:
686+
fileId: int
687+
executorId: int
688+
configuration: String
689+
resultsConfig: [resultsConfig]
690+
691+
resultsConfig:
692+
sourceName
693+
destinationName
694+
isDirectory
695+
fileUrlEnvVariable
696+
697+
usage: client.create_build(job_id, json.dumps({"fileId":123213...))
698+
"""
699+
def create_build(self, job_id, build_config={}):
700+
build = self.post(path="me/jobs/{}/builds".format(job_id), payload=build_config, headers={'Content-type': 'application/json', 'Accept': 'application/json'})
701+
logger.info("build %s: %s (%s) " % (build['id'], build['buildNumber'], build['state'] ))
702+
return build
703+
704+
""" Update job
705+
"""
706+
def upload_job(self, job_id,job_name, content):
707+
job = self.post(path="me/jobs/{}".format(job_id), payload={"name": job_name, "content": content})
708+
709+
logger.info("Job %s: %s (%s) created" % (job['id'], job['name'], job['type'] ))
710+
return job
711+
712+
""" Update job
713+
"""
714+
def update_job(self, job_id,job_name, content):
715+
job = self.post(path="me/jobs/{}".format(job_id), payload={"name": job_name, "content": content})
716+
717+
logger.info("Job %s: %s (%s) created" % (job['id'], job['name'], job['type'] ))
718+
return job
719+
720+
""" Delete job
721+
"""
722+
def delete_job(self, job_id):
723+
return self.delete("me/jobs/{}".format(job_id))
724+
725+
""" Delete build
726+
"""
727+
def delete_build(self, job_id, build_id):
728+
return self.delete("me/jobs/{}/builds/{}".format(job_id, build_id))
729+
730+
""" Get build output files
731+
"""
732+
def download_build_output_files(self, job_id, build_id, results_folder="results", tags=None):
733+
files = self.get("me/jobs/{}/builds/{}/output-file-set/files{}".format(job_id, build_id, "?tag[]=".format(tags) if tags else "" ))
734+
for file in files['data']:
735+
if file['state'] == "READY":
736+
full_path = "%s/%s" % (results_folder, file['name'])
737+
if not os.path.exists(results_folder):
738+
os.makedirs(results_folder)
739+
740+
url = "me/files/%s/file" % (file['id'])
741+
prog = DownloadProgressBar()
742+
self.download(url, full_path, callback=lambda pos, total: prog.update(int(pos), int(total)))
743+
print("")
744+
else:
745+
logger.info("File %s is not ready" % file['name'])
746+
if( len(files['data']) == 0 ):
747+
logger.info("No files to download")
748+
logger.info("")
749+
750+
630751
""" Downloads test run files to a directory hierarchy
631752
"""
632753
def download_test_run(self, project_id, test_run_id):
@@ -736,6 +857,7 @@ def format_epilog(self, formatter):
736857
upload-application <project-id> <filename> Upload application to project
737858
upload-test <project-id> <filename> Upload test file to project
738859
upload-data <project-id> <filename> Upload additional data file to project
860+
upload-file <filename> Upload to "Files"
739861
set-project-config <project-id> <config-json>
740862
Change the project config parameters as facilitated by the API:
741863
http://docs.testdroid.com/_pages/client.html#project-config
@@ -788,6 +910,7 @@ def get_commands(self):
788910
"upload-application": self.upload_application_file,
789911
"upload-test": self.upload_test_file,
790912
"upload-data": self.upload_data_file,
913+
"upload-file": self.upload_file,
791914
"set-project-config": self.set_project_config,
792915
"start-test-run": self.start_test_run,
793916
"start-test-run-using-config": self.start_test_run_using_config,
@@ -799,7 +922,15 @@ def get_commands(self):
799922
"device-run-files": self.get_device_run_files,
800923
"list-input-files": self.print_input_files,
801924
"download-test-run": self.download_test_run,
802-
"download-test-screenshots": self.download_test_screenshots
925+
"jobs": self.print_jobs,
926+
"builds": self.print_builds,
927+
"create-job": self.create_job,
928+
"update-job": self.update_job,
929+
"create-build": self.create_build,
930+
"delete-job": self.delete_job,
931+
"delete-build": self.delete_build,
932+
"download-builds-files": self.download_build_output_files
933+
803934
}
804935
return commands
805936

0 commit comments

Comments
 (0)