~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/tests/cdash/builder.py

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#
2
 
# builder.py - PJSIP test scenarios builder
3
 
#
4
 
# Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
5
 
#
6
 
# This program is free software; you can redistribute it and/or modify
7
 
# it under the terms of the GNU General Public License as published by
8
 
# the Free Software Foundation; either version 2 of the License, or
9
 
# (at your option) any later version.
10
 
#
11
 
# This program is distributed in the hope that it will be useful,
12
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
# GNU General Public License for more details.
15
 
#
16
 
# You should have received a copy of the GNU General Public License
17
 
# along with this program; if not, write to the Free Software
18
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
#
20
 
 
21
 
import ccdash
22
 
import os
23
 
import platform
24
 
import re
25
 
import subprocess
26
 
import sys
27
 
import time
28
 
 
29
 
class Operation:
30
 
    """\
31
 
    The Operation class describes the individual ccdash operation to be
32
 
    performed.
33
 
 
34
 
    """
35
 
    # Types:
36
 
    UPDATE = "update"           # Update operation
37
 
    CONFIGURE = "configure"     # Configure operation
38
 
    BUILD = "build"             # Build operation
39
 
    TEST = "test"               # Unit test operation
40
 
 
41
 
    def __init__(self, type, cmdline, name="", wdir=""):
42
 
        self.type = type
43
 
        self.cmdline = cmdline
44
 
        self.name = name
45
 
        self.wdir = wdir
46
 
        if self.type==self.TEST and not self.name:
47
 
            raise "name required for tests"
48
 
 
49
 
    def encode(self, base_dir):
50
 
        s = [self.type]
51
 
        if self.type == self.TEST:
52
 
            s.append(self.name)
53
 
        if self.type != self.UPDATE:
54
 
            s.append(self.cmdline)
55
 
        s.append("-w")
56
 
        if self.wdir:
57
 
            s.append(base_dir + "/" + self.wdir)
58
 
        else:
59
 
            s.append(base_dir)
60
 
        return s
61
 
 
62
 
 
63
 
#
64
 
# Update operation
65
 
#
66
 
update_ops = [Operation(Operation.UPDATE, "")]
67
 
 
68
 
#
69
 
# The standard library tests (e.g. pjlib-test, pjsip-test, etc.)
70
 
#
71
 
std_test_ops= [
72
 
    Operation(Operation.TEST, "./pjlib-test$SUFFIX", name="pjlib test",
73
 
              wdir="pjlib/bin"),
74
 
    Operation(Operation.TEST, "./pjlib-util-test$SUFFIX",
75
 
              name="pjlib-util test", wdir="pjlib-util/bin"),
76
 
    Operation(Operation.TEST, "./pjnath-test$SUFFIX", name="pjnath test",
77
 
              wdir="pjnath/bin"),
78
 
    Operation(Operation.TEST, "./pjmedia-test$SUFFIX", name="pjmedia test",
79
 
              wdir="pjmedia/bin"),
80
 
    Operation(Operation.TEST, "./pjsip-test$SUFFIX", name="pjsip test",
81
 
              wdir="pjsip/bin")
82
 
]
83
 
 
84
 
#
85
 
# These are pjsua Python based unit test operations
86
 
#
87
 
def build_pjsua_test_ops(pjsua_exe=""):
88
 
    ops = []
89
 
    if pjsua_exe:
90
 
        exe = " -e ../../pjsip-apps/bin/" + pjsua_exe
91
 
    else:
92
 
        exe = ""
93
 
    cwd = os.getcwd()
94
 
    os.chdir("../pjsua")
95
 
    os.system("python runall.py --list > list")
96
 
    f = open("list", "r")
97
 
    for e in f:
98
 
        e = e.rstrip("\r\n ")
99
 
        (mod,param) = e.split(None,2)
100
 
        name = mod[4:mod.find(".py")] + "_" + \
101
 
               param[param.find("/")+1:param.find(".py")]
102
 
        ops.append(Operation(Operation.TEST, "python run.py" + exe + " " + \
103
 
                             e, name=name, wdir="tests/pjsua"))
104
 
    f.close()
105
 
    os.remove("list")
106
 
    os.chdir(cwd)
107
 
    return ops
108
 
 
109
 
#
110
 
# Get gcc version
111
 
#
112
 
def gcc_version(gcc):
113
 
    proc = subprocess.Popen(gcc + " -v", stdout=subprocess.PIPE,
114
 
                            stderr=subprocess.STDOUT, shell=True)
115
 
    ver = ""
116
 
    while True:
117
 
        s = proc.stdout.readline()
118
 
        if not s:
119
 
            break
120
 
        if s.find("gcc version") >= 0:
121
 
            ver = s.split(None, 3)[2]
122
 
            break
123
 
    proc.wait()
124
 
    return "gcc-" + ver
125
 
 
126
 
#
127
 
# Get Visual Studio version
128
 
#
129
 
def vs_get_version():
130
 
    proc = subprocess.Popen("cl", stdout=subprocess.PIPE,
131
 
                            stderr=subprocess.STDOUT)
132
 
    while True:
133
 
        s = proc.stdout.readline()
134
 
        if s=="":
135
 
            break
136
 
        pos = s.find("Version")
137
 
        if pos > 0:
138
 
            proc.wait()
139
 
            s = s[pos+8:]
140
 
            ver = s.split(None, 1)[0]
141
 
            major = ver[0:2]
142
 
            if major=="12":
143
 
                return "vs6"
144
 
            elif major=="13":
145
 
                return "vs2003"
146
 
            elif major=="14":
147
 
                return "vs2005"
148
 
            elif major=="15":
149
 
                return "vs2008"
150
 
            else:
151
 
                return "vs-" + major
152
 
    proc.wait()
153
 
    return "vs-unknown"
154
 
 
155
 
 
156
 
#
157
 
# Test config
158
 
#
159
 
class BaseConfig:
160
 
    def __init__(self, base_dir, url, site, group, options=None):
161
 
        self.base_dir = base_dir
162
 
        self.url = url
163
 
        self.site = site
164
 
        self.group = group
165
 
        self.options = options
166
 
 
167
 
#
168
 
# Base class for test configurator
169
 
#
170
 
class TestBuilder:
171
 
    def __init__(self, config, build_config_name="",
172
 
                 user_mak="", config_site="", exclude=[], not_exclude=[]):
173
 
        self.config = config                        # BaseConfig instance
174
 
        self.build_config_name = build_config_name  # Optional build suffix
175
 
        self.user_mak = user_mak                    # To be put in user.mak
176
 
        self.config_site = config_site              # To be put in config_s..
177
 
        self.saved_user_mak = ""                    # To restore user.mak
178
 
        self.saved_config_site = ""                 # To restore config_s..
179
 
        self.exclude = exclude                      # List of exclude pattern
180
 
        self.not_exclude = not_exclude              # List of include pattern
181
 
        self.ccdash_args = []                       # ccdash cmd line
182
 
 
183
 
    def stamp(self):
184
 
        return time.strftime("%Y%m%d-%H%M", time.localtime())
185
 
 
186
 
    def pre_action(self):
187
 
        # Override user.mak
188
 
        name = self.config.base_dir + "/user.mak"
189
 
        if os.access(name, os.F_OK):
190
 
            f = open(name, "r")
191
 
            self.saved_user_mak = f.read()
192
 
            f.close()
193
 
        if True:
194
 
            f = open(name, "w")
195
 
            f.write(self.user_mak)
196
 
            f.close()
197
 
        # Override config_site.h
198
 
        name = self.config.base_dir + "/pjlib/include/pj/config_site.h"
199
 
        if os.access(name, os.F_OK):
200
 
            f = open(name, "r")
201
 
            self.saved_config_site= f.read()
202
 
            f.close()
203
 
        if True:
204
 
            f = open(name, "wt")
205
 
            f.write(self.config_site)
206
 
            f.close()
207
 
 
208
 
 
209
 
    def post_action(self):
210
 
        # Restore user.mak
211
 
        name = self.config.base_dir + "/user.mak"
212
 
        f = open(name, "wt")
213
 
        f.write(self.saved_user_mak)
214
 
        f.close()
215
 
        # Restore config_site.h
216
 
        name = self.config.base_dir + "/pjlib/include/pj/config_site.h"
217
 
        f = open(name, "wt")
218
 
        f.write(self.saved_config_site)
219
 
        f.close()
220
 
 
221
 
    def build_tests(self):
222
 
        # This should be overridden by subclasses
223
 
        pass
224
 
 
225
 
    def execute(self):
226
 
        if len(self.ccdash_args)==0:
227
 
            self.build_tests()
228
 
        self.pre_action()
229
 
        mandatory_op = ["update", "configure", "build"]
230
 
        counter = 0
231
 
        for a in self.ccdash_args:
232
 
            # Check if this test is in exclusion list
233
 
            fullcmd = " ".join(a)
234
 
            excluded = False
235
 
            included = False
236
 
            for pat in self.exclude:
237
 
                if pat and re.search(pat, fullcmd) != None:
238
 
                    excluded = True
239
 
                    break
240
 
            if excluded:
241
 
                for pat in self.not_exclude:
242
 
                    if pat and re.search(pat, fullcmd) != None:
243
 
                        included = True
244
 
                        break
245
 
            if excluded and not included:
246
 
                if len(fullcmd)>60:
247
 
                    fullcmd = fullcmd[0:60] + ".."
248
 
                print "Skipping '%s'" % (fullcmd)
249
 
                continue
250
 
 
251
 
            b = ["ccdash.py"]
252
 
            b.extend(a)
253
 
            a = b
254
 
            #print a
255
 
            try:
256
 
                rc = ccdash.main(a)
257
 
            except Exception, e:
258
 
                errmsg = str(e)
259
 
                print "**** Error: ccdash got exception %s ****" % errmsg
260
 
                rc = -1
261
 
            except:
262
 
                print "**** Error: ccdash got unknown exception ****"
263
 
                rc = -1
264
 
 
265
 
            if rc!=0 and a[1] in mandatory_op:
266
 
                print "Stopping because of error.."
267
 
                break
268
 
            counter = counter + 1
269
 
        self.post_action()
270
 
 
271
 
 
272
 
#
273
 
# GNU test configurator
274
 
#
275
 
class GNUTestBuilder(TestBuilder):
276
 
    """\
277
 
    This class creates list of tests suitable for GNU targets.
278
 
 
279
 
    """
280
 
    def __init__(self, config, build_config_name="", user_mak="", \
281
 
                 config_site="", cross_compile="", exclude=[], not_exclude=[]):
282
 
        """\
283
 
        Parameters:
284
 
        config              - BaseConfig instance
285
 
        build_config_name   - Optional name to be added as suffix to the build
286
 
                              name. Sample: "min-size", "O4", "TLS", etc.
287
 
        user_mak            - Contents to be put on user.mak
288
 
        config_site         - Contents to be put on config_site.h
289
 
        cross_compile       - Optional cross-compile prefix. Must include the
290
 
                              trailing dash, e.g. "arm-unknown-linux-"
291
 
        exclude             - List of regular expression patterns for tests
292
 
                              that will be excluded from the run
293
 
        not_exclude         - List of regular expression patterns for tests
294
 
                              that will be run regardless of whether they
295
 
                              match the excluded pattern.
296
 
 
297
 
        """
298
 
        TestBuilder.__init__(self, config, build_config_name=build_config_name,
299
 
                             user_mak=user_mak, config_site=config_site,
300
 
                             exclude=exclude, not_exclude=not_exclude)
301
 
        self.cross_compile = cross_compile
302
 
        if self.cross_compile and self.cross_compile[-1] != '-':
303
 
            self.cross_compile.append("-")
304
 
 
305
 
    def build_tests(self):
306
 
        if self.cross_compile:
307
 
            suffix = "-" + self.cross_compile[0:-1]
308
 
            build_name =  self.cross_compile + \
309
 
                          gcc_version(self.cross_compile + "gcc")
310
 
        else:
311
 
            proc = subprocess.Popen("sh "+self.config.base_dir+"/config.guess",
312
 
                                    shell=True, stdout=subprocess.PIPE)
313
 
            plat = proc.stdout.readline().rstrip(" \r\n")
314
 
            build_name =  plat + "-"+gcc_version(self.cross_compile + "gcc")
315
 
            suffix = "-" + plat
316
 
 
317
 
        if self.build_config_name:
318
 
            build_name = build_name + "-" + self.build_config_name
319
 
        cmds = []
320
 
        cmds.extend(update_ops)
321
 
        cmds.append(Operation(Operation.CONFIGURE, "sh ./configure"))
322
 
        if sys.platform=="win32":
323
 
            # Don't build python module on Mingw
324
 
            cmds.append(Operation(Operation.BUILD,
325
 
                            "sh -c 'make distclean && make dep && make'"))
326
 
        else:
327
 
            cmds.append(Operation(Operation.BUILD,
328
 
                            "sh -c 'make distclean && make dep && make" + \
329
 
                            " && cd pjsip-apps/src/python && " + \
330
 
                            "python setup.py clean build'"))
331
 
 
332
 
        cmds.extend(std_test_ops)
333
 
        cmds.extend(build_pjsua_test_ops())
334
 
        self.ccdash_args = []
335
 
        for c in cmds:
336
 
            c.cmdline = c.cmdline.replace("$SUFFIX", suffix)
337
 
            args = c.encode(self.config.base_dir)
338
 
            args.extend(["-U", self.config.url,
339
 
                         "-S", self.config.site,
340
 
                         "-T", self.stamp(),
341
 
                         "-B", build_name,
342
 
                         "-G", self.config.group])
343
 
            args.extend(self.config.options)
344
 
            self.ccdash_args.append(args)
345
 
 
346
 
#
347
 
# MSVC test configurator
348
 
#
349
 
class MSVCTestBuilder(TestBuilder):
350
 
    """\
351
 
    This class creates list of tests suitable for Visual Studio builds.
352
 
    You need to set the MSVC environment variables (typically by calling
353
 
    vcvars32.bat) prior to running this class.
354
 
 
355
 
    """
356
 
    def __init__(self, config, target="Release|Win32", build_config_name="",
357
 
                 config_site="", exclude=[], not_exclude=[]):
358
 
        """\
359
 
        Parameters:
360
 
        config              - BaseConfig instance
361
 
        target              - Visual Studio build configuration to build.
362
 
                              Sample: "Debug|Win32", "Release|Win32".
363
 
        build_config_name   - Optional name to be added as suffix to the build
364
 
                              name. Sample: "Debug", "Release", "IPv6", etc.
365
 
        config_site         - Contents to be put on config_site.h
366
 
        exclude             - List of regular expression patterns for tests
367
 
                              that will be excluded from the run
368
 
        not_exclude         - List of regular expression patterns for tests
369
 
                              that will be run regardless of whether they
370
 
                              match the excluded pattern.
371
 
 
372
 
        """
373
 
        TestBuilder.__init__(self, config, build_config_name=build_config_name,
374
 
                             config_site=config_site, exclude=exclude,
375
 
                             not_exclude=not_exclude)
376
 
        self.target = target.lower()
377
 
 
378
 
    def build_tests(self):
379
 
 
380
 
        (vsbuild,sys) = self.target.split("|",2)
381
 
 
382
 
        build_name = sys + "-" + vs_get_version() + "-" + vsbuild
383
 
 
384
 
        if self.build_config_name:
385
 
            build_name = build_name + "-" + self.build_config_name
386
 
 
387
 
        vccmd = "vcbuild.exe /nologo /nohtmllog /nocolor /rebuild " + \
388
 
                "pjproject-vs8.sln " + " \"" + self.target + "\""
389
 
 
390
 
        suffix = "-i386-win32-vc8-" + vsbuild
391
 
        pjsua = "pjsua_vc8"
392
 
        if vsbuild=="debug":
393
 
            pjsua = pjsua + "d"
394
 
 
395
 
        cmds = []
396
 
        cmds.extend(update_ops)
397
 
        cmds.append(Operation(Operation.CONFIGURE, "CMD /C echo Nothing to do"))
398
 
        cmds.append(Operation(Operation.BUILD, vccmd))
399
 
        cmds.extend(std_test_ops)
400
 
        cmds.extend(build_pjsua_test_ops(pjsua))
401
 
 
402
 
        self.ccdash_args = []
403
 
        for c in cmds:
404
 
            c.cmdline = c.cmdline.replace("$SUFFIX", suffix)
405
 
            args = c.encode(self.config.base_dir)
406
 
            args.extend(["-U", self.config.url,
407
 
                         "-S", self.config.site,
408
 
                         "-T", self.stamp(),
409
 
                         "-B", build_name,
410
 
                         "-G", self.config.group])
411
 
            args.extend(self.config.options)
412
 
            self.ccdash_args.append(args)
413
 
 
414
 
 
415
 
#
416
 
# Symbian test configurator
417
 
#
418
 
class SymbianTestBuilder(TestBuilder):
419
 
    """\
420
 
    This class creates list of tests suitable for Symbian builds. You need to
421
 
    set the command line build settings prior to running this class (typically
422
 
    that involves setting the EPOCROOT variable and current device).
423
 
 
424
 
    """
425
 
    def __init__(self, config, target="gcce urel", build_config_name="",
426
 
                 config_site="", exclude=[], not_exclude=[]):
427
 
        """\
428
 
        Parameters:
429
 
        config              - BaseConfig instance
430
 
        target              - Symbian target to build. Default is "gcce urel".
431
 
        build_config_name   - Optional name to be added as suffix to the build
432
 
                              name. Sample: "APS", "VAS", etc.
433
 
        config_site         - Contents to be put on config_site.h
434
 
        exclude             - List of regular expression patterns for tests
435
 
                              that will be excluded from the run
436
 
        not_exclude         - List of regular expression patterns for tests
437
 
                              that will be run regardless of whether they
438
 
                              match the excluded pattern.
439
 
 
440
 
        """
441
 
        TestBuilder.__init__(self, config, build_config_name=build_config_name,
442
 
                             config_site=config_site, exclude=exclude,
443
 
                             not_exclude=not_exclude)
444
 
        self.target = target.lower()
445
 
 
446
 
    def build_tests(self):
447
 
 
448
 
        # Check that EPOCROOT is set
449
 
        if not "EPOCROOT" in os.environ:
450
 
            print "Error: EPOCROOT environment variable is not set"
451
 
            sys.exit(1)
452
 
        epocroot = os.environ["EPOCROOT"]
453
 
        # EPOCROOT must have trailing backslash
454
 
        if epocroot[-1] != "\\":
455
 
            epocroot = epocroot + "\\"
456
 
            os.environ["EPOCROOT"] = epocroot
457
 
        sdk1 = epocroot.split("\\")[-2]
458
 
 
459
 
        # Check that correct device is set
460
 
        proc = subprocess.Popen("devices", stdout=subprocess.PIPE,
461
 
                                stderr=subprocess.STDOUT, shell=True)
462
 
        sdk2 = ""
463
 
        while True:
464
 
            line = proc.stdout.readline()
465
 
            if line.find("- default") > 0:
466
 
                sdk2 = line.split(":",1)[0]
467
 
                break
468
 
        proc.wait()
469
 
 
470
 
        if sdk1 != sdk2:
471
 
            print "Error: default SDK in device doesn't match EPOCROOT"
472
 
            print "Default device SDK =", sdk2
473
 
            print "EPOCROOT SDK =", sdk1
474
 
            sys.exit(1)
475
 
 
476
 
        build_name = sdk2.replace("_", "-") + "-" + \
477
 
                     self.target.replace(" ", "-")
478
 
 
479
 
        if self.build_config_name:
480
 
            build_name = build_name + "-" + self.build_config_name
481
 
 
482
 
        cmdline = "cmd /C \"cd build.symbian && bldmake bldfiles && abld build %s\"" % (self.target)
483
 
 
484
 
        cmds = []
485
 
        cmds.extend(update_ops)
486
 
        cmds.append(Operation(Operation.CONFIGURE, "CMD /C echo Nothing to do"))
487
 
        cmds.extend([Operation(Operation.BUILD, cmdline)])
488
 
 
489
 
        self.ccdash_args = []
490
 
        suffix = ""
491
 
        for c in cmds:
492
 
            c.cmdline = c.cmdline.replace("$SUFFIX", suffix)
493
 
            args = c.encode(self.config.base_dir)
494
 
            args.extend(["-U", self.config.url,
495
 
                         "-S", self.config.site,
496
 
                         "-T", self.stamp(),
497
 
                         "-B", build_name,
498
 
                         "-G", self.config.group])
499
 
            args.extend(self.config.options)
500
 
            self.ccdash_args.append(args)