summaryrefslogtreecommitdiff
path: root/testing/framework/TestSCons_time.py
diff options
context:
space:
mode:
Diffstat (limited to 'testing/framework/TestSCons_time.py')
-rw-r--r--testing/framework/TestSCons_time.py361
1 files changed, 361 insertions, 0 deletions
diff --git a/testing/framework/TestSCons_time.py b/testing/framework/TestSCons_time.py
new file mode 100644
index 0000000..547e264
--- /dev/null
+++ b/testing/framework/TestSCons_time.py
@@ -0,0 +1,361 @@
+"""
+TestSCons_time.py: a testing framework for the scons-test.py script
+
+A TestSCons_time environment object is created via the usual invocation:
+
+ test = TestSCons_time()
+
+TestSCons_time is a subclass of TestCommon, which is in turn is a subclass
+of TestCmd), and hence has available all of the methods and attributes
+from those classes, as well as any overridden or additional methods or
+attributes defined in this subclass.
+"""
+
+# Copyright (c) 2001 - 2019 The SCons Foundation
+
+__revision__ = "testing/framework/TestSCons_time.py e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 00:04:47 bdeegan"
+
+import os
+import os.path
+import sys
+
+from TestCommon import *
+from TestCommon import __all__
+# some of the scons_time tests may need regex-based matching:
+from TestSCons import search_re, search_re_in_list
+
+__all__.extend(['TestSCons_time',])
+
+SConstruct = """\
+from __future__ import print_function
+import os
+print("SConstruct file directory:", os.getcwd())
+"""
+
+scons_py = """\
+#!/usr/bin/env python
+import os
+import sys
+
+def write_args(fp, args):
+ fp.write(args[0] + '\\n')
+ for arg in args[1:]:
+ fp.write(' ' + arg + '\\n')
+
+write_args(sys.stdout, sys.argv)
+for arg in sys.argv[1:]:
+ if arg[:10] == '--profile=':
+ with open(arg[10:], 'w') as profile:
+ profile.write('--profile\\n')
+ write_args(profile, sys.argv)
+ break
+sys.stdout.write('SCONS_LIB_DIR = ' + os.environ['SCONS_LIB_DIR'] + '\\n')
+with open('SConstruct', 'r') as f:
+ script = f.read()
+exec(script)
+"""
+
+aegis_py = """\
+#!/usr/bin/env python
+import os
+import sys
+
+script_dir = 'src/script'
+if not os.path.exists(script_dir):
+ os.makedirs(script_dir)
+with open(script_dir + '/scons.py', 'w') as f:
+ f.write(r'''%s''')
+""" % scons_py
+
+
+svn_py = """\
+#!/usr/bin/env python
+import os
+import sys
+
+dir = sys.argv[-1]
+script_dir = dir + '/src/script'
+os.makedirs(script_dir)
+with open(script_dir + '/scons.py', 'w') as f:
+ f.write(r'''%s''')
+""" % scons_py
+
+
+git_py = """\
+#!/usr/bin/env python
+import os
+import sys
+
+dir = sys.argv[-1]
+script_dir = dir + '/src/script'
+os.makedirs(script_dir)
+with open(script_dir + '/scons.py', 'w') as f:
+ f.write(r'''%s''')
+""" % scons_py
+
+
+logfile_contents = """\
+Memory before reading SConscript files: 100%(index)s
+Memory after reading SConscript files: 200%(index)s
+Memory before building targets: 300%(index)s
+Memory after building targets: 400%(index)s
+Object counts:
+ pre- post- pre- post-
+ read read build build Class
+ 101%(index)s 102%(index)s 103%(index)s 104%(index)s Action.CommandAction
+ 201%(index)s 202%(index)s 203%(index)s 204%(index)s Action.CommandGeneratorAction
+ 301%(index)s 302%(index)s 303%(index)s 304%(index)s Action.FunctionAction
+ 401%(index)s 402%(index)s 403%(index)s 404%(index)s Action.LazyAction
+ 501%(index)s 502%(index)s 503%(index)s 504%(index)s Action.ListAction
+ 601%(index)s 602%(index)s 603%(index)s 604%(index)s Builder.BuilderBase
+ 701%(index)s 702%(index)s 703%(index)s 704%(index)s Builder.CompositeBuilder
+ 801%(index)s 802%(index)s 803%(index)s 804%(index)s Builder.ListBuilder
+ 901%(index)s 902%(index)s 903%(index)s 904%(index)s Builder.MultiStepBuilder
+ 1001%(index)s 1002%(index)s 1003%(index)s 1004%(index)s Builder.OverrideWarner
+ 1101%(index)s 1102%(index)s 1103%(index)s 1104%(index)s Environment.Base
+ 1201%(index)s 1202%(index)s 1203%(index)s 1204%(index)s Environment.EnvironmentClone
+ 1301%(index)s 1302%(index)s 1303%(index)s 1304%(index)s Environment.OverrideEnvironment
+ 1401%(index)s 1402%(index)s 1403%(index)s 1404%(index)s Executor.Executor
+ 1501%(index)s 1502%(index)s 1503%(index)s 1504%(index)s Node.FS
+ 1601%(index)s 1602%(index)s 1603%(index)s 1604%(index)s Node.FS.Base
+ 1701%(index)s 1702%(index)s 1703%(index)s 1704%(index)s Node.FS.Dir
+ 1801%(index)s 1802%(index)s 1803%(index)s 1804%(index)s Node.FS.File
+ 1901%(index)s 1902%(index)s 1904%(index)s 1904%(index)s Node.FS.RootDir
+ 2001%(index)s 2002%(index)s 2003%(index)s 2004%(index)s Node.Node
+Total build time: 11.123456 seconds
+Total SConscript file execution time: 22.234567 seconds
+Total SCons execution time: 33.345678 seconds
+Total command execution time: 44.456789 seconds
+"""
+
+
+profile_py = """\
+%(body)s
+
+import profile
+
+try: dispatch = profile.Profile.dispatch
+except AttributeError: pass
+else: dispatch['c_exception'] = profile.Profile.trace_dispatch_return
+
+prof = profile.Profile()
+prof.runcall(%(call)s)
+prof.dump_stats(r'%(profile_name)s')
+"""
+
+
+class TestSCons_time(TestCommon):
+ """Class for testing the scons-time script.
+
+ This provides a common place for initializing scons-time tests,
+ eliminating the need to begin every test with the same repeated
+ initializations.
+ """
+
+ def __init__(self, **kw):
+ """Initialize an SCons_time testing object.
+
+ If they're not overridden by keyword arguments, this
+ initializes the object with the following default values:
+
+ program = 'scons-time'
+ interpreter = ['python', '-tt']
+ match = match_exact
+ workdir = ''
+
+ The workdir value means that, by default, a temporary workspace
+ directory is created for a TestSCons_time environment.
+ In addition, this method changes directory (chdir) to the
+ workspace directory, so an explicit "chdir = '.'" on all of the
+ run() method calls is not necessary.
+ """
+
+ self.orig_cwd = os.getcwd()
+ try:
+ script_dir = os.environ['SCONS_SCRIPT_DIR']
+ except KeyError:
+ pass
+ else:
+ os.chdir(script_dir)
+ if 'program' not in kw:
+ p = os.environ.get('SCONS_TIME')
+ if not p:
+ p = 'scons-time'
+ if not os.path.exists(p):
+ p = 'scons-time.py'
+ kw['program'] = p
+
+ if 'interpreter' not in kw:
+ kw['interpreter'] = [python,]
+ if sys.version_info[0] < 3:
+ kw['interpreter'].append('-tt')
+
+ if 'match' not in kw:
+ kw['match'] = match_exact
+
+ if 'workdir' not in kw:
+ kw['workdir'] = ''
+
+ TestCommon.__init__(self, **kw)
+
+ def archive_split(self, path):
+ if path[-7:] == '.tar.gz':
+ return path[:-7], path[-7:]
+ else:
+ return os.path.splitext(path)
+
+ def fake_logfile(self, logfile_name, index=0):
+ self.write(self.workpath(logfile_name), logfile_contents % locals())
+
+ def profile_data(self, profile_name, python_name, call, body):
+ profile_name = self.workpath(profile_name)
+ python_name = self.workpath(python_name)
+ d = {
+ 'profile_name' : profile_name,
+ 'python_name' : python_name,
+ 'call' : call,
+ 'body' : body,
+ }
+ self.write(python_name, profile_py % d)
+ self.run(program = python_name, interpreter = sys.executable)
+
+ def tempdir_re(self, *args):
+ """
+ Returns a regular expression to match a scons-time
+ temporary directory.
+ """
+ import re
+ import tempfile
+
+ sep = re.escape(os.sep)
+ tempdir = tempfile.gettempdir()
+
+ try:
+ realpath = os.path.realpath
+ except AttributeError:
+ pass
+ else:
+ tempdir = realpath(tempdir)
+
+ args = (tempdir, 'scons-time-',) + args
+ x = os.path.join(*args)
+ x = re.escape(x)
+ x = x.replace('time\\-', 'time\\-[^%s]*' % sep)
+ return x
+
+ def write_fake_aegis_py(self, name):
+ name = self.workpath(name)
+ self.write(name, aegis_py)
+ os.chmod(name, 0o755)
+ return name
+
+ def write_fake_scons_py(self):
+ self.subdir('src', ['src', 'script'])
+ self.write('src/script/scons.py', scons_py)
+
+ def write_fake_svn_py(self, name):
+ name = self.workpath(name)
+ self.write(name, svn_py)
+ os.chmod(name, 0o755)
+ return name
+
+ def write_fake_git_py(self, name):
+ name = self.workpath(name)
+ self.write(name, git_py)
+ os.chmod(name, 0o755)
+ return name
+
+ def write_sample_directory(self, archive, dir, files):
+ dir = self.workpath(dir)
+ for name, content in files:
+ path = os.path.join(dir, name)
+ d, f = os.path.split(path)
+ if not os.path.isdir(d):
+ os.makedirs(d)
+ with open(path, 'w') as f:
+ f.write(content)
+ return dir
+
+ def write_sample_tarfile(self, archive, dir, files):
+ import shutil
+ try:
+ import tarfile
+
+ except ImportError:
+
+ self.skip_test('no tarfile module\n')
+
+ else:
+
+ base, suffix = self.archive_split(archive)
+
+ mode = {
+ '.tar' : 'w',
+ '.tar.gz' : 'w:gz',
+ '.tgz' : 'w:gz',
+ }
+
+ tar = tarfile.open(archive, mode[suffix])
+ for name, content in files:
+ path = os.path.join(dir, name)
+ with open(path, 'wb') as f:
+ f.write(bytearray(content,'utf-8'))
+ tarinfo = tar.gettarinfo(path, path)
+ tarinfo.uid = 111
+ tarinfo.gid = 111
+ tarinfo.uname = 'fake_user'
+ tarinfo.gname = 'fake_group'
+ with open(path, 'rb') as f:
+ tar.addfile(tarinfo, f)
+ tar.close()
+ shutil.rmtree(dir)
+ return self.workpath(archive)
+
+ def write_sample_zipfile(self, archive, dir, files):
+ import shutil
+ try:
+ import zipfile
+ except ImportError:
+
+ sys.stderr.write('no zipfile module\n')
+ self.no_result()
+
+ else:
+
+ zip = zipfile.ZipFile(archive, 'w')
+ for name, content in files:
+ path = os.path.join(dir, name)
+ with open(path, 'w') as f:
+ f.write(content)
+ zip.write(path)
+ zip.close()
+ shutil.rmtree(dir)
+ return self.workpath(archive)
+
+ sample_project_files = [
+ ('SConstruct', SConstruct),
+ ]
+
+ def write_sample_project(self, archive, dir=None):
+ base, suffix = self.archive_split(archive)
+
+ write_sample = {
+ '.tar' : self.write_sample_tarfile,
+ '.tar.gz' : self.write_sample_tarfile,
+ '.tgz' : self.write_sample_tarfile,
+ '.zip' : self.write_sample_zipfile,
+ }.get(suffix, self.write_sample_directory)
+
+ if not dir:
+ dir = base
+
+ os.mkdir(dir)
+ path = write_sample(archive, dir, self.sample_project_files)
+
+ return path
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4: