mirror of https://github.com/KLayout/klayout.git
329 lines
13 KiB
Python
Executable File
329 lines
13 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
#===============================================================================
|
|
# File: "macbuild/macQAT.py"
|
|
#
|
|
# The top Python script to run "ut_runner" after building KLayout
|
|
# (http://www.klayout.de/index.php) version 0.29.7 or later on different
|
|
# Apple Mac OSX platforms.
|
|
#
|
|
# This script must be copied to a "*.macQAT/" directory to run.
|
|
#===============================================================================
|
|
import sys
|
|
import os
|
|
import datetime
|
|
from time import sleep
|
|
import platform
|
|
import optparse
|
|
import subprocess
|
|
|
|
#-------------------------------------------------------------------------------
|
|
## To set global variables including present directory and platform info.
|
|
#
|
|
#-------------------------------------------------------------------------------
|
|
def SetGlobals():
|
|
global ProjectDir # project directory where "ut_runner" exists
|
|
global RunnerUsage # True to print the usage of 'ut_runner'
|
|
global StartKLayout # True to start the KLayout main GUI window
|
|
global Run # True to run this script
|
|
global ContinueOnError # True to continue after an error
|
|
global TestsExcluded # list of tests to exclude
|
|
global Arguments # other arguments
|
|
global GitSHA1 # Git's short SHA1 value of the HEAD
|
|
global TimeStamp # time stamp
|
|
global WorkDir # work directory name
|
|
global LogFile # log file name
|
|
global Usage # string on usage
|
|
global DryRun # dry-run mode; print the command line and exit
|
|
# auxiliary variables on platform
|
|
global System # 6-tuple from platform.uname()
|
|
global Node # - do -
|
|
global Release # - do -
|
|
global Version # - do -
|
|
global Machine # - do -
|
|
global Processor # - do -
|
|
global Bit # machine bit-size
|
|
|
|
Usage = "\n"
|
|
Usage += "----------------------------------------------------------------------------------------\n"
|
|
Usage += "<< Usage of 'macQAT.py' >>\n"
|
|
Usage += " for running 'ut_runner' after building KLayout.\n"
|
|
Usage += "\n"
|
|
Usage += "$ [python] ./macQAT.py\n"
|
|
Usage += " option & argument : descriptions | default value\n"
|
|
Usage += " -----------------------------------------------------------------+---------------\n"
|
|
Usage += " [-u|--usage] : print usage of 'ut_runner'and exit | disabled\n"
|
|
Usage += " |\n"
|
|
Usage += " [-k|--klayout] : just start the KLayout main GUI window | disabled\n"
|
|
Usage += " <-r|--run> : run this script | disabled\n"
|
|
Usage += " [-s|--stop] : stop on error | disabled\n"
|
|
Usage += " [-x|--exclude <tests>] : exclude test(s) such as 'pymod,pya' | ''\n"
|
|
Usage += " : you can use this option multiple times |\n"
|
|
Usage += " [-a|--args <string>] : arguments other than '-x' and '-c' | ''\n"
|
|
Usage += " : you can use this option multiple times |\n"
|
|
Usage += " [--dryrun] : print the command line and exit | disabled\n"
|
|
Usage += " [-?|--?] : print this usage and exit | disabled\n"
|
|
Usage += "--------------------------------------------------------------------+-------------------\n"
|
|
|
|
ProjectDir = os.getcwd()
|
|
RunnerUsage = False
|
|
StartKLayout = False
|
|
Run = False
|
|
ContinueOnError = True
|
|
TestsExcluded = list()
|
|
Arguments = list()
|
|
GitSHA1 = GetGitShortSHA1()
|
|
TimeStamp = GetTimeStamp()
|
|
WorkDir = "QATest_%s_%s__%s" % (GitSHA1, TimeStamp, os.path.basename(ProjectDir) )
|
|
LogFile = WorkDir + ".log"
|
|
DryRun = False
|
|
|
|
(System, Node, Release, Version, Machine, Processor) = platform.uname()
|
|
|
|
#-------------------------------------------------------------------------------
|
|
## Get git's short SHA1 value of the HEAD
|
|
#
|
|
# @return SHA1 value string
|
|
#-------------------------------------------------------------------------------
|
|
def GetGitShortSHA1():
|
|
command = "git rev-parse --short HEAD 2>/dev/null"
|
|
sha1val = os.popen( command ).read().strip()
|
|
return sha1val
|
|
|
|
#-------------------------------------------------------------------------------
|
|
## Get the time stamp
|
|
#
|
|
# @return time stamp string
|
|
#-------------------------------------------------------------------------------
|
|
def GetTimeStamp():
|
|
ts = datetime.datetime.today()
|
|
return "%04d_%02d%02d_%02d%02d" % (ts.year, ts.month, ts.day, ts.hour, ts.minute)
|
|
|
|
#-------------------------------------------------------------------------------
|
|
## To parse the command line arguments
|
|
#
|
|
#-------------------------------------------------------------------------------
|
|
def ParseCommandLineArguments():
|
|
global Usage
|
|
global RunnerUsage
|
|
global StartKLayout
|
|
global Run
|
|
global ContinueOnError
|
|
global TestsExcluded
|
|
global Arguments
|
|
global DryRun
|
|
|
|
p = optparse.OptionParser( usage=Usage )
|
|
p.add_option( '-u', '--usage',
|
|
action='store_true',
|
|
dest='runner_usage',
|
|
default=False,
|
|
help="print usage of 'ut_runner' and exit (false)" )
|
|
|
|
p.add_option( '-k', '--klayout',
|
|
action='store_true',
|
|
dest='start_KLayout',
|
|
default=False,
|
|
help='just start the KLayout main GUI window (false)' )
|
|
|
|
p.add_option( '-r', '--run',
|
|
action='store_true',
|
|
dest='runme',
|
|
default=False,
|
|
help='run this script (false)' )
|
|
|
|
p.add_option( '-s', '--stop',
|
|
action='store_true',
|
|
dest='stop_on_error',
|
|
default=False,
|
|
help='stop on error (false)' )
|
|
|
|
p.add_option( '-x', '--exclude',
|
|
action='append',
|
|
dest='exclude_tests',
|
|
help="exclude test(s) such as 'pymod,pya' ('')" )
|
|
|
|
p.add_option( '-a', '--args',
|
|
action='append',
|
|
dest='arguments',
|
|
help="arguments other than '-x' and '-c' ('')" )
|
|
|
|
p.add_option( '--dryrun',
|
|
action='store_true',
|
|
dest='dryrun',
|
|
default=False,
|
|
help='print the command line and exit (false)' )
|
|
|
|
p.add_option( '-?', '--??',
|
|
action='store_true',
|
|
dest='checkusage',
|
|
default=False,
|
|
help='check usage (false)' )
|
|
|
|
p.set_defaults( runner_usage = False,
|
|
start_KLayout = False,
|
|
runme = False,
|
|
stop_on_error = False,
|
|
exclude_tests = list(),
|
|
arguments = list(),
|
|
dryrun = False,
|
|
checkusage = False )
|
|
|
|
opt, args = p.parse_args()
|
|
if opt.checkusage:
|
|
print(Usage)
|
|
quit()
|
|
|
|
RunnerUsage = opt.runner_usage
|
|
StartKLayout = opt.start_KLayout
|
|
Run = opt.runme
|
|
ContinueOnError = not opt.stop_on_error
|
|
if not len(opt.exclude_tests) == 0:
|
|
excluded_tests = list()
|
|
for item in opt.exclude_tests:
|
|
excluded_tests += [ subitem.strip() for subitem in item.split(',') ]
|
|
TestsExcluded = sorted(list(set(excluded_tests)))
|
|
else:
|
|
TestsExcluded = []
|
|
Arguments = opt.arguments
|
|
DryRun = opt.dryrun
|
|
|
|
#-------------------------------------------------------------------------------
|
|
## Hide/Show the private directory
|
|
#
|
|
#-------------------------------------------------------------------------------
|
|
def HidePrivateDir():
|
|
if os.path.isdir( "../private" ):
|
|
os.rename( "../private", "../private.stash" )
|
|
|
|
def ShowPrivateDir():
|
|
if os.path.isdir( "../private.stash" ):
|
|
os.rename( "../private.stash", "../private" )
|
|
|
|
#-------------------------------------------------------------------------------
|
|
## Export environment variables for "ut_runner"
|
|
#
|
|
#-------------------------------------------------------------------------------
|
|
def ExportEnvVariables():
|
|
global ProjectDir
|
|
global WorkDir
|
|
global MyEnviron # my environment variables; can be independently used later
|
|
|
|
# In older versions of subprocess module, 'env=None' argument is not provided
|
|
MyEnviron = os.environ.copy()
|
|
MyEnviron[ 'TESTSRC' ] = ".."
|
|
MyEnviron[ 'TESTTMP' ] = WorkDir
|
|
if System == "Darwin":
|
|
MyEnviron[ 'DYLD_LIBRARY_PATH' ] = "%s:%s/db_plugins:%s/lay_plugins:%s/pymod" % (ProjectDir, ProjectDir, ProjectDir, ProjectDir)
|
|
MyEnviron[ 'MallocNanoZone' ] = "0"
|
|
MyEnviron[ 'ASAN_OPTIONS' ] = "ast_unwind_on_malloc=0:verbosity=1:detect_leaks=0:abort_on_error=0:halt_on_error=0:symbolize=1"
|
|
for env in [ 'TESTSRC', 'TESTTMP', 'DYLD_LIBRARY_PATH', 'MallocNanoZone', 'ASAN_OPTIONS' ]:
|
|
os.environ[env] = MyEnviron[env]
|
|
else:
|
|
MyEnviron[ 'LD_LIBRARY_PATH' ] = "%s:%s/db_plugins:%s/lay_plugins:%s/pymod" % (ProjectDir, ProjectDir, ProjectDir, ProjectDir)
|
|
for env in [ 'TESTSRC', 'TESTTMP', 'LD_LIBRARY_PATH' ]:
|
|
os.environ[env] = MyEnviron[env]
|
|
|
|
#-------------------------------------------------------------------------------
|
|
## Start the KLayout main GUI window
|
|
#
|
|
#-------------------------------------------------------------------------------
|
|
def StartKLatyouGUIWindow():
|
|
if System == "Darwin":
|
|
command = "./klayout.app/Contents/MacOS/klayout"
|
|
else:
|
|
command = "./klayout"
|
|
|
|
subprocess.call( command, shell=False )
|
|
|
|
#-------------------------------------------------------------------------------
|
|
## Run the tester
|
|
#
|
|
# @param[in] command command string to run
|
|
# @param[in] logfile log file name
|
|
#-------------------------------------------------------------------------------
|
|
def RunTester( command, logfile="" ):
|
|
proc = subprocess.Popen( command.split(),
|
|
stdout=subprocess.PIPE, \
|
|
stderr=subprocess.STDOUT, \
|
|
universal_newlines=True )
|
|
|
|
if not logfile == "":
|
|
with proc.stdout, open( logfile, 'w' ) as file:
|
|
for line in proc.stdout:
|
|
sys.stdout.write(line)
|
|
file.write(line)
|
|
proc.wait()
|
|
else:
|
|
with proc.stdout:
|
|
for line in proc.stdout:
|
|
sys.stdout.write(line)
|
|
proc.wait()
|
|
|
|
#-------------------------------------------------------------------------------
|
|
# Main function
|
|
#-------------------------------------------------------------------------------
|
|
def Main():
|
|
#-------------------------------------------------------
|
|
# [1] Initialize
|
|
#-------------------------------------------------------
|
|
SetGlobals()
|
|
ParseCommandLineArguments()
|
|
ExportEnvVariables()
|
|
|
|
#-------------------------------------------------------
|
|
# [2] Print the runner's usage
|
|
#-------------------------------------------------------
|
|
if RunnerUsage:
|
|
command = './ut_runner --help-all'
|
|
RunTester( command )
|
|
quit()
|
|
|
|
#-------------------------------------------------------
|
|
# [3] Start the KLayout main GUI window
|
|
#-------------------------------------------------------
|
|
if StartKLayout:
|
|
StartKLatyouGUIWindow()
|
|
|
|
#-------------------------------------------------------
|
|
# [4] Run the unit tester
|
|
#-------------------------------------------------------
|
|
if not Run and not StartKLayout:
|
|
print( "! pass <-r|--run> option to run the QA tests" )
|
|
print( "! pass <-k|--klayout> option to start the KLayout main GUI window" )
|
|
print(Usage)
|
|
quit()
|
|
|
|
if Run:
|
|
command = './ut_runner'
|
|
if ContinueOnError:
|
|
command += " -c"
|
|
for item in TestsExcluded:
|
|
command += ' -x %s' % item
|
|
if not len(Arguments) == 0:
|
|
for arg in Arguments:
|
|
command += " %s" % arg
|
|
|
|
print( "" )
|
|
print( "### Dumping the log to <%s>" % LogFile )
|
|
print( "------------------------------------------------------------------------" )
|
|
print( " Git SHA1 = %s" % GitSHA1 )
|
|
print( " Time stamp = %s" % TimeStamp )
|
|
print( " Command line = %s" % command )
|
|
print( "------------------------------------------------------------------------" )
|
|
if DryRun:
|
|
quit()
|
|
sleep(1.0)
|
|
HidePrivateDir()
|
|
RunTester( command, logfile=LogFile )
|
|
ShowPrivateDir()
|
|
|
|
#===================================================================================
|
|
if __name__ == "__main__":
|
|
Main()
|
|
|
|
#---------------
|
|
# End of file
|
|
#---------------
|