summaryrefslogtreecommitdiffstats
path: root/tools/coverity/coverity.py
blob: cefc82c00158c7d56a6691d5d60a54dad7ce7dc3 (plain)
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
#!/usr/bin/python
# Copyright (c) 2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
Runs Coverity Prevent on a build of Chromium.

This script should be run in a Visual Studio Command Prompt, so that the
INCLUDE, LIB, and PATH environment variables are set properly for Visual
Studio.

Usage examples:
  coverity.py
  coverity.py --dry-run
  coverity.py --target=debug
  %comspec% /c ""C:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat"
      x86 && C:\Python24\python.exe C:\coverity.py"

For a full list of options, pass the '--help' switch.

See http://support.microsoft.com/kb/308569 for running this script as a
Scheduled Task on Windows XP.

"""

import optparse
import os
import subprocess
import sys
import time

# TODO(wtc): Change these constants to command-line flags, particularly the
# ones that are paths.  Set default values for the flags.

CHROMIUM_SOURCE_DIR = 'E:\\chromium.latest'

# Relative to CHROMIUM_SOURCE_DIR.
CHROMIUM_SOLUTION_FILE = 'src\\chrome\\chrome.sln'

# Relative to CHROMIUM_SOURCE_DIR.
CHROMIUM_SOLUTION_DIR = 'src\\chrome'

COVERITY_BIN_DIR = 'C:\\coverity\\prevent-mingw-4.4.0\\bin'

COVERITY_INTERMEDIATE_DIR = 'C:\\coverity\\cvbuild\\cr_int'

COVERITY_DATABASE_DIR = 'C:\\coverity\\cvbuild\\db'

COVERITY_ANALYZE_OPTIONS = ('--cxx --security --concurrency '
                            '--enable ATOMICITY '
                            '--enable MISSING_LOCK '
                            '--enable DELETE_VOID '
                            '--checker-option PASS_BY_VALUE:size_threshold:16 '
                            '--checker-option '
                            'USE_AFTER_FREE:allow_simple_use:false '
                            '--enable-constraint-fpp '
                            '--enable-callgraph-metrics')

COVERITY_PRODUCT = 'Chromium'

COVERITY_USER = 'admin'

# Relative to CHROMIUM_SOURCE_DIR.  Contains the pid of this script.
LOCK_FILE = 'coverity.lock'

def _RunCommand(cmd, dry_run, shell=False):
  """Runs the command if dry_run is false, otherwise just prints the command."""
  print cmd
  # TODO(wtc): Check the return value of subprocess.call, which is the return
  # value of the command.
  if not dry_run:
    subprocess.call(cmd, shell=shell)

def main(options, args):
  """Runs all the selected tests for the given build type and target."""
  # Create the lock file to prevent another instance of this script from
  # running.
  lock_filename = '%s\\%s' % (CHROMIUM_SOURCE_DIR, LOCK_FILE)
  try:
    lock_file = os.open(lock_filename,
                        os.O_CREAT | os.O_EXCL | os.O_TRUNC | os.O_RDWR)
  except OSError, err:
    print 'Failed to open lock file:\n  ' + str(err)
    return 1

  # Write the pid of this script (the python.exe process) to the lock file.
  os.write(lock_file, str(os.getpid()))

  options.target = options.target.title()

  start_time = time.time()

  print 'Change directory to ' + CHROMIUM_SOURCE_DIR
  os.chdir(CHROMIUM_SOURCE_DIR)

  cmd = 'gclient sync'
  _RunCommand(cmd, options.dry_run, shell=True)
  print 'Elapsed time: %ds' % (time.time() - start_time)

  # Do a clean build.  Remove the build output directory first.
  # TODO(wtc): Consider using Python's rmtree function in the shutil module,
  # or the RemoveDirectory function in
  # trunk/tools/buildbot/scripts/common/chromium_utils.py.
  cmd = 'rmdir /s /q %s\\%s\\%s' % (CHROMIUM_SOURCE_DIR,
                                    CHROMIUM_SOLUTION_DIR, options.target)
  _RunCommand(cmd, options.dry_run, shell=True)
  print 'Elapsed time: %ds' % (time.time() - start_time)

  cmd = '%s\\cov-build.exe --dir %s devenv.com %s\\%s /build %s' % (
      COVERITY_BIN_DIR, COVERITY_INTERMEDIATE_DIR, CHROMIUM_SOURCE_DIR,
      CHROMIUM_SOLUTION_FILE, options.target)
  _RunCommand(cmd, options.dry_run)
  print 'Elapsed time: %ds' % (time.time() - start_time)

  cmd = '%s\\cov-analyze.exe --dir %s %s' % (COVERITY_BIN_DIR,
                                             COVERITY_INTERMEDIATE_DIR,
                                             COVERITY_ANALYZE_OPTIONS)
  _RunCommand(cmd, options.dry_run)
  print 'Elapsed time: %ds' % (time.time() - start_time)

  cmd = ('%s\\cov-commit-defects.exe --dir %s --datadir %s --product %s '
         '--user %s') % (COVERITY_BIN_DIR, COVERITY_INTERMEDIATE_DIR,
                         COVERITY_DATABASE_DIR, COVERITY_PRODUCT,
                         COVERITY_USER)
  _RunCommand(cmd, options.dry_run)

  print 'Total time: %ds' % (time.time() - start_time)

  os.close(lock_file)
  os.remove(lock_filename)

  return 0

if '__main__' == __name__:
  option_parser = optparse.OptionParser()
  option_parser.add_option('', '--dry-run', action='store_true', default=False,
                           help='print but don\'t run the commands')
  option_parser.add_option('', '--target', default='Release',
                           help='build target (Debug or Release)')
  options, args = option_parser.parse_args()

  result = main(options, args)
  sys.exit(result)