File: macQAT.py

package info (click to toggle)
klayout 0.30.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 292,204 kB
  • sloc: cpp: 2,068,428; ruby: 47,823; xml: 26,924; python: 14,404; sh: 1,812; tcl: 212; perl: 170; makefile: 112; ansic: 42
file content (328 lines) | stat: -rwxr-xr-x 13,154 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
#!/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
#---------------