-
Notifications
You must be signed in to change notification settings - Fork 11
/
testaux.py.in
218 lines (199 loc) · 8.95 KB
/
testaux.py.in
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
# ============================================================================
# Copyright (c) 2011-2012 University of Pennsylvania
# Copyright (c) 2013-2014 Andreas Schuh
# All rights reserved.
#
# See COPYING file for license information or visit
# http://opensource.andreasschuh.com/cmake-basis/download.html#license
#
# Contact: Andreas Schuh <andreas.schuh.84@gmail.com>
# ============================================================================
##############################################################################
# @file testaux.py
# @brief Utilities for test implementations.
##############################################################################
# ============================================================================
# modules
# ============================================================================
from __future__ import unicode_literals
import os
import io
import sys
import shutil
import getopt
import socket
from basis import basis
# ============================================================================
# constants
# ============================================================================
TEST_NAME = os.path.splitext(os.path.basename(basis.exename()))[0]
BASIS_DIR = '@TESTING_BASIS_DIR@'
RESSOURCES_DIR = os.path.join('@PROJECT_TESTING_DIR@/ressources', TEST_NAME)
SOURCE_DIR = os.path.join('@TESTING_OUTPUT_DIR@', TEST_NAME, 'source')
BUILD_DIR = os.path.join('@TESTING_OUTPUT_DIR@', TEST_NAME, 'build')
# ============================================================================
# helpers
# ============================================================================
# ----------------------------------------------------------------------------
def parse_arguments(flags='v', options=['verbose'], allow_args=False):
"Parse test arguments."
sys.stdout.write("<DartMeasurement name=\"Host Name\" type=\"string\">");
sys.stdout.write(socket.gethostname());
sys.stdout.write("</DartMeasurement>\n");
try:
opts, args = getopt.gnu_getopt(sys.argv[1:], flags, options)
if not allow_args and len(args) > 0:
sys.stderr.write("Unhandled positional parameters given!\n")
sys.stderr.write("Arguments: " + repr(args) + "\n")
sys.exit(1)
except getopt.GetoptError as e:
sys.stderr.write(basis.tostring(e) + '\n')
sys.exit(1)
if allow_args: return opts, args
else: return opts
# ----------------------------------------------------------------------------
def create_project(name, *args, **kwargs):
"Create test project."
print("Creating test project...")
description = kwargs.get('description', 'This is a test project.')
use = kwargs.get('use', [])
useopt = kwargs.get('useopt', [])
if os.path.exists(SOURCE_DIR): shutil.rmtree(SOURCE_DIR)
# attention: changing the project name will affect the tests!
create_cmd = ['basis.basisproject', 'create',
'--name', name,
'--description', description,
'--root', SOURCE_DIR]
create_cmd.extend(args)
for pkg in use:
create_cmd.extend(['--use', pkg])
for pkg in useopt:
create_cmd.extend(['--useopt', pkg])
basis.execute(create_cmd, verbose=True)
print("Creating test project... - done")
# ----------------------------------------------------------------------------
def update_project(name, *args, **kwargs):
"Update test project."
print("Updating test project...")
use = kwargs.get('use', [])
useopt = kwargs.get('useopt', [])
if not os.path.isdir(SOURCE_DIR):
raise Exception("Cannot update non-existing project in %s" % SOURCE_DIR)
update_cmd = ['basis.basisproject', 'update', '--root', SOURCE_DIR]
update_cmd.extend(args)
for pkg in use:
update_cmd.extend(['--use', pkg])
for pkg in useopt:
update_cmd.extend(['--useopt', pkg])
basis.execute(update_cmd, verbose=True)
print("Updating test project... - done")
# ----------------------------------------------------------------------------
def build_project(verbose=0, cmakeopts=None):
"Build test project."
print("Configuring test project...")
if os.path.exists(BUILD_DIR): shutil.rmtree(BUILD_DIR)
os.makedirs(BUILD_DIR)
wd=os.getcwd()
os.chdir(BUILD_DIR)
config_cmd=['@CMAKE_COMMAND@',
'-DBUILD_DOCUMENTATION:BOOL=OFF',
'-DBUILD_CHANGELOG:BOOL=OFF',
'-DBUILD_TESTING:BOOL=ON',
'-DBASIS_DIR:PATH=' + BASIS_DIR,
'-DCMAKE_BUILD_TYPE:STRING=@TESTING_BUILD_TYPE@']
if cmakeopts != None: config_cmd.extend(cmakeopts)
if '@TESTING_C_FLAGS@'.strip() != '':
config_cmd.append('-DCMAKE_C_FLAGS:STRING=@TESTING_C_FLAGS@')
if '@TESTING_CXX_FLAGS@'.strip() != '':
config_cmd.append('-DCMAKE_CXX_FLAGS:STRING=@TESTING_CXX_FLAGS@')
if '@TESTING_EXE_LINKER_FLAGS@'.strip() != '':
config_cmd.append('-DCMAKE_EXE_LINKER_FLAGS:STRING=@TESTING_EXE_LINKER_FLAGS@')
if '@TESTING_SHARED_LINKER_FLAGS@'.strip() != '':
config_cmd.append('-DCMAKE_SHARED_LINKER_FLAGS:STRING=@TESTING_SHARED_LINKER_FLAGS@')
if '@TESTING_MODULE_LINKER_FLAGS@'.strip() != '':
config_cmd.append('-DCMAKE_MODULE_LINKER_FLAGS:STRING=@TESTING_MODULE_LINKER_FLAGS@')
if verbose > 0:
config_cmd.append('-DBASIS_VERBOSE:BOOL=ON')
if verbose > 1:
config_cmd.append('-DBASIS_DEBUG:BOOL=ON')
config_cmd.append(SOURCE_DIR)
basis.execute(config_cmd, verbose=True)
print("Configuring test project... - done")
print("Building test project...")
build_cmd = None
if sys.platform == 'win32':
solution_file = False
for f in os.listdir(BUILD_DIR):
if f.endswith('.sln'):
solution_file = os.path.join(BUILD_DIR, f)
break
if solution_file:
build_cmd = ['devenv', solution_file, '/build']
if '@TESTING_BUILD_TYPE@' != '': build_cmd.append('@TESTING_BUILD_TYPE@')
else: build_cmd.append('Release')
if not build_cmd:
build_cmd = ['make']
if verbose > 0: build_cmd.append('VERBOSE=1')
basis.execute(build_cmd, verbose=True)
print("Building test project... - done")
os.chdir(wd)
# ----------------------------------------------------------------------------
def run_tests(verbose=0):
"""Run tests by invoking CTest in the build directory."""
wd=os.getcwd()
os.chdir(BUILD_DIR)
test_cmd=['@CMAKE_CTEST_COMMAND@', '-V']
if verbose > 0: test_cmd.append('-V')
if sys.platform == 'win32':
test_cmd.append('-C')
if '@TESTING_BUILD_TYPE@' != '': test_cmd.append('@TESTING_BUILD_TYPE@')
else: test_cmd.append('Release')
test_cmd.extend(sys.argv[1:])
basis.execute(test_cmd, verbose=True)
os.chdir(wd)
# ----------------------------------------------------------------------------
def add_file(file, prefix='.', name=None):
"""Copy file from ressources directory to project source tree.
@param [in] file File path relative to top directory of ressources tree.
@param [in] prefix Path prefix relative to project source tree. Defaults
to the root of the project source tree itself.
@param [in] name Name of file in project source tree. Defaults to the
name of the file given by @p file.
"""
if not name: name = os.path.basename(file)
dstdir = os.path.join(SOURCE_DIR, prefix, os.path.dirname(file))
if not os.path.isdir(dstdir):
os.makedirs(dstdir)
dst = os.path.join(dstdir, name)
shutil.copy(os.path.join(RESSOURCES_DIR, file), dst)
print("Added file " + dst)
# ----------------------------------------------------------------------------
def add_dependency(package, required=True):
"Add package to list of project dependencies."
fp = io.open(os.path.join(SOURCE_DIR, 'BasisProject.cmake'), "r")
code = fp.read()
fp.close()
if required:
code = code.replace('#<dependency>', package + '\n #<dependency>')
else:
code = code.replace('#<optional-dependency>', package + '\n #<optional-dependency>')
fp = io.open(os.path.join(SOURCE_DIR, 'BasisProject.cmake'), "w")
fp.write(code)
fp.close()
if required: print("Added dependency on " + package)
else: print("Added optional dependency on " + package)
# ----------------------------------------------------------------------------
def add_cmake_code(cmakefile, code):
"Add CMake code to CMakeLists.txt file."
cmakefile = os.path.join(SOURCE_DIR, cmakefile)
if not os.path.exists(cmakefile):
raise Exception('File ' + cmakefile + ' does not exist!')
fp = io.open(os.path.join(SOURCE_DIR, cmakefile), 'a')
fp.write(code + '\n')
fp.close()
print("Modified file " + cmakefile)
# ----------------------------------------------------------------------------
def cleanup():
"Cleanup source and binary tree."
if os.path.exists(SOURCE_DIR): shutil.rmtree(SOURCE_DIR)
if os.path.exists(BUILD_DIR): shutil.rmtree(BUILD_DIR)