# ============================================================ # Script used to launch the iOS tests on the device while also # watching asynchronously for the changes from the log file # ============================================================ import argparse import sys import os import re import threading import time import shlex import subprocess from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler class WatchDog(FileSystemEventHandler): __log_file_name = None __log_file_path = None __should_watch_logs = True __watch_logs_thread = None def __init__(self, log_file_name): self.__log_file_name = log_file_name def get_watch_logs_thread(self): return self.__watch_logs_thread def get_log_file_path(self): return self.__log_file_path def on_created(self, event): if self.__log_file_name in event.src_path and self.__log_file_path == None: self.__log_file_path = event.src_path self.__watch_logs_thread = threading.Thread(target=self.watch_logs) self.__watch_logs_thread.start() def watch_logs(self): fileBytePos = 0 while self.__should_watch_logs: inFile = open(self.__log_file_path,'r') inFile.seek(fileBytePos) data = inFile.read() sys.stdout.write(data) sys.stdout.flush() fileBytePos = inFile.tell() inFile.close() time.sleep(0.1) print "Logs watcher terminated successfully!" def stop_watch(self): self.__should_watch_logs = False def launch_tests(command): subprocess.call(shlex.split(command)) if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--testsCommand', help='The xcodebuild tests command used for launching the tests') parser.add_argument('--derivedDataPath', help='The path to the derived data folder') parser.add_argument('--logFileName', help='The tests log file name') args = parser.parse_args() if args.testsCommand is None and args.derivedDataPath is None and args.logFileName is None: parser.print_help() sys.exit(1) print "\nRUNNING WITH ARGS: " print "--testsCommand %s" % args.testsCommand print "--derivedDataPath %s" % args.derivedDataPath print "--logFileName %s" % args.logFileName if not os.path.exists(args.derivedDataPath): print "DERIVED DATA PATH DOES NOT EXIST! CREATING..." os.makedirs(args.derivedDataPath) observer = Observer() watch_logs = WatchDog(args.logFileName) observer.schedule(watch_logs, path=args.derivedDataPath, recursive=True) observer.start() tests_thread = threading.Thread(target=launch_tests, args=(args.testsCommand,)) tests_thread.daemon = True tests_thread.start() try: while tests_thread.is_alive(): time.sleep(1) except KeyboardInterrupt: print "\nThe script was stopped by a Keyboard interrupt!" finally: # Sleep to ensure that the final logs are printed as well time.sleep(1) observer.stop() watch_logs.stop_watch() watch_logs_thread = watch_logs.get_watch_logs_thread() # Joining the thread to ensure the watch logs thread ends properly if watch_logs_thread is None: if watch_logs.get_log_file_path() == None: print "ERROR: Missing tests logs!" else: watch_logs_thread.join()