• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2#
3# Copyright 2009 Google Inc. All Rights Reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met:
8#
9#     * Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11#     * Redistributions in binary form must reproduce the above
12# copyright notice, this list of conditions and the following disclaimer
13# in the documentation and/or other materials provided with the
14# distribution.
15#     * Neither the name of Google Inc. nor the names of its
16# contributors may be used to endorse or promote products derived from
17# this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31"""Tests for run_tests_util.py test runner script."""
32
33__author__ = 'vladl@google.com (Vlad Losev)'
34
35import os
36import re
37import sets
38import unittest
39
40import run_tests_util
41
42
43GTEST_DBG_DIR = 'scons/build/dbg/gtest/scons'
44GTEST_OPT_DIR = 'scons/build/opt/gtest/scons'
45GTEST_OTHER_DIR = 'scons/build/other/gtest/scons'
46
47
48def AddExeExtension(path):
49  """Appends .exe to the path on Windows or Cygwin."""
50
51  if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN:
52    return path + '.exe'
53  else:
54    return path
55
56
57class FakePath(object):
58  """A fake os.path module for testing."""
59
60  def __init__(self, current_dir=os.getcwd(), known_paths=None):
61    self.current_dir = current_dir
62    self.tree = {}
63    self.path_separator = os.sep
64
65    # known_paths contains either absolute or relative paths. Relative paths
66    # are absolutized with self.current_dir.
67    if known_paths:
68      self._AddPaths(known_paths)
69
70  def _AddPath(self, path):
71    ends_with_slash = path.endswith('/')
72    path = self.abspath(path)
73    if ends_with_slash:
74      path += self.path_separator
75    name_list = path.split(self.path_separator)
76    tree = self.tree
77    for name in name_list[:-1]:
78      if not name:
79        continue
80      if name in tree:
81        tree = tree[name]
82      else:
83        tree[name] = {}
84        tree = tree[name]
85
86    name = name_list[-1]
87    if name:
88      if name in tree:
89        assert tree[name] == 1
90      else:
91        tree[name] = 1
92
93  def _AddPaths(self, paths):
94    for path in paths:
95      self._AddPath(path)
96
97  def PathElement(self, path):
98    """Returns an internal representation of directory tree entry for path."""
99    tree = self.tree
100    name_list = self.abspath(path).split(self.path_separator)
101    for name in name_list:
102      if not name:
103        continue
104      tree = tree.get(name, None)
105      if tree is None:
106        break
107
108    return tree
109
110  # Silences pylint warning about using standard names.
111  # pylint: disable-msg=C6409
112  def normpath(self, path):
113    return os.path.normpath(path)
114
115  def abspath(self, path):
116    return self.normpath(os.path.join(self.current_dir, path))
117
118  def isfile(self, path):
119    return self.PathElement(self.abspath(path)) == 1
120
121  def isdir(self, path):
122    return type(self.PathElement(self.abspath(path))) == type(dict())
123
124  def basename(self, path):
125    return os.path.basename(path)
126
127  def dirname(self, path):
128    return os.path.dirname(path)
129
130  def join(self, *kargs):
131    return os.path.join(*kargs)
132
133
134class FakeOs(object):
135  """A fake os module for testing."""
136  P_WAIT = os.P_WAIT
137
138  def __init__(self, fake_path_module):
139    self.path = fake_path_module
140
141    # Some methods/attributes are delegated to the real os module.
142    self.environ = os.environ
143
144  # pylint: disable-msg=C6409
145  def listdir(self, path):
146    assert self.path.isdir(path)
147    return self.path.PathElement(path).iterkeys()
148
149  def spawnv(self, wait, executable, *kargs):
150    assert wait == FakeOs.P_WAIT
151    return self.spawn_impl(executable, kargs)
152
153
154class GetTestsToRunTest(unittest.TestCase):
155  """Exercises TestRunner.GetTestsToRun."""
156
157  def NormalizeGetTestsToRunResults(self, results):
158    """Normalizes path data returned from GetTestsToRun for comparison."""
159
160    def NormalizePythonTestPair(pair):
161      """Normalizes path data in the (directory, python_script) pair."""
162
163      return (os.path.normpath(pair[0]), os.path.normpath(pair[1]))
164
165    def NormalizeBinaryTestPair(pair):
166      """Normalizes path data in the (directory, binary_executable) pair."""
167
168      directory, executable = map(os.path.normpath, pair)
169
170      # On Windows and Cygwin, the test file names have the .exe extension, but
171      # they can be invoked either by name or by name+extension. Our test must
172      # accommodate both situations.
173      if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN:
174        executable = re.sub(r'\.exe$', '', executable)
175      return (directory, executable)
176
177    python_tests = sets.Set(map(NormalizePythonTestPair, results[0]))
178    binary_tests = sets.Set(map(NormalizeBinaryTestPair, results[1]))
179    return (python_tests, binary_tests)
180
181  def AssertResultsEqual(self, results, expected):
182    """Asserts results returned by GetTestsToRun equal to expected results."""
183
184    self.assertEqual(self.NormalizeGetTestsToRunResults(results),
185                     self.NormalizeGetTestsToRunResults(expected),
186                     'Incorrect set of tests returned:\n%s\nexpected:\n%s' %
187                     (results, expected))
188
189  def setUp(self):
190    self.fake_os = FakeOs(FakePath(
191        current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)),
192        known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'),
193                     AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'),
194                     'test/gtest_color_test.py']))
195    self.fake_configurations = ['dbg', 'opt']
196    self.test_runner = run_tests_util.TestRunner(script_dir='.',
197                                                 injected_os=self.fake_os,
198                                                 injected_subprocess=None)
199
200  def testBinaryTestsOnly(self):
201    """Exercises GetTestsToRun with parameters designating binary tests only."""
202
203    # A default build.
204    self.AssertResultsEqual(
205        self.test_runner.GetTestsToRun(
206            ['gtest_unittest'],
207            '',
208            False,
209            available_configurations=self.fake_configurations),
210        ([],
211         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
212
213    # An explicitly specified directory.
214    self.AssertResultsEqual(
215        self.test_runner.GetTestsToRun(
216            [GTEST_DBG_DIR, 'gtest_unittest'],
217            '',
218            False,
219            available_configurations=self.fake_configurations),
220        ([],
221         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
222
223    # A particular configuration.
224    self.AssertResultsEqual(
225        self.test_runner.GetTestsToRun(
226            ['gtest_unittest'],
227            'other',
228            False,
229            available_configurations=self.fake_configurations),
230        ([],
231         [(GTEST_OTHER_DIR, GTEST_OTHER_DIR + '/gtest_unittest')]))
232
233    # All available configurations
234    self.AssertResultsEqual(
235        self.test_runner.GetTestsToRun(
236            ['gtest_unittest'],
237            'all',
238            False,
239            available_configurations=self.fake_configurations),
240        ([],
241         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'),
242          (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')]))
243
244    # All built configurations (unbuilt don't cause failure).
245    self.AssertResultsEqual(
246        self.test_runner.GetTestsToRun(
247            ['gtest_unittest'],
248            '',
249            True,
250            available_configurations=self.fake_configurations + ['unbuilt']),
251        ([],
252         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'),
253          (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')]))
254
255    # A combination of an explicit directory and a configuration.
256    self.AssertResultsEqual(
257        self.test_runner.GetTestsToRun(
258            [GTEST_DBG_DIR, 'gtest_unittest'],
259            'opt',
260            False,
261            available_configurations=self.fake_configurations),
262        ([],
263         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'),
264          (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')]))
265
266    # Same test specified in an explicit directory and via a configuration.
267    self.AssertResultsEqual(
268        self.test_runner.GetTestsToRun(
269            [GTEST_DBG_DIR, 'gtest_unittest'],
270            'dbg',
271            False,
272            available_configurations=self.fake_configurations),
273        ([],
274         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
275
276    # All built configurations + explicit directory + explicit configuration.
277    self.AssertResultsEqual(
278        self.test_runner.GetTestsToRun(
279            [GTEST_DBG_DIR, 'gtest_unittest'],
280            'opt',
281            True,
282            available_configurations=self.fake_configurations),
283        ([],
284         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'),
285          (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')]))
286
287  def testPythonTestsOnly(self):
288    """Exercises GetTestsToRun with parameters designating Python tests only."""
289
290    # A default build.
291    self.AssertResultsEqual(
292        self.test_runner.GetTestsToRun(
293            ['gtest_color_test.py'],
294            '',
295            False,
296            available_configurations=self.fake_configurations),
297        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
298         []))
299
300    # An explicitly specified directory.
301    self.AssertResultsEqual(
302        self.test_runner.GetTestsToRun(
303            [GTEST_DBG_DIR, 'test/gtest_color_test.py'],
304            '',
305            False,
306            available_configurations=self.fake_configurations),
307        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
308         []))
309
310    # A particular configuration.
311    self.AssertResultsEqual(
312        self.test_runner.GetTestsToRun(
313            ['gtest_color_test.py'],
314            'other',
315            False,
316            available_configurations=self.fake_configurations),
317        ([(GTEST_OTHER_DIR, 'test/gtest_color_test.py')],
318         []))
319
320    # All available configurations
321    self.AssertResultsEqual(
322        self.test_runner.GetTestsToRun(
323            ['test/gtest_color_test.py'],
324            'all',
325            False,
326            available_configurations=self.fake_configurations),
327        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'),
328          (GTEST_OPT_DIR, 'test/gtest_color_test.py')],
329         []))
330
331    # All built configurations (unbuilt don't cause failure).
332    self.AssertResultsEqual(
333        self.test_runner.GetTestsToRun(
334            ['gtest_color_test.py'],
335            '',
336            True,
337            available_configurations=self.fake_configurations + ['unbuilt']),
338        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'),
339          (GTEST_OPT_DIR, 'test/gtest_color_test.py')],
340         []))
341
342    # A combination of an explicit directory and a configuration.
343    self.AssertResultsEqual(
344        self.test_runner.GetTestsToRun(
345            [GTEST_DBG_DIR, 'gtest_color_test.py'],
346            'opt',
347            False,
348            available_configurations=self.fake_configurations),
349        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'),
350          (GTEST_OPT_DIR, 'test/gtest_color_test.py')],
351         []))
352
353    # Same test specified in an explicit directory and via a configuration.
354    self.AssertResultsEqual(
355        self.test_runner.GetTestsToRun(
356            [GTEST_DBG_DIR, 'gtest_color_test.py'],
357            'dbg',
358            False,
359            available_configurations=self.fake_configurations),
360        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
361         []))
362
363    # All built configurations + explicit directory + explicit configuration.
364    self.AssertResultsEqual(
365        self.test_runner.GetTestsToRun(
366            [GTEST_DBG_DIR, 'gtest_color_test.py'],
367            'opt',
368            True,
369            available_configurations=self.fake_configurations),
370        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'),
371          (GTEST_OPT_DIR, 'test/gtest_color_test.py')],
372         []))
373
374  def testCombinationOfBinaryAndPythonTests(self):
375    """Exercises GetTestsToRun with mixed binary/Python tests."""
376
377    # Use only default configuration for this test.
378
379    # Neither binary nor Python tests are specified so find all.
380    self.AssertResultsEqual(
381        self.test_runner.GetTestsToRun(
382            [],
383            '',
384            False,
385            available_configurations=self.fake_configurations),
386        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
387         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
388
389    # Specifying both binary and Python tests.
390    self.AssertResultsEqual(
391        self.test_runner.GetTestsToRun(
392            ['gtest_unittest', 'gtest_color_test.py'],
393            '',
394            False,
395            available_configurations=self.fake_configurations),
396        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
397         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
398
399    # Specifying binary tests suppresses Python tests.
400    self.AssertResultsEqual(
401        self.test_runner.GetTestsToRun(
402            ['gtest_unittest'],
403            '',
404            False,
405            available_configurations=self.fake_configurations),
406        ([],
407         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
408
409   # Specifying Python tests suppresses binary tests.
410    self.AssertResultsEqual(
411        self.test_runner.GetTestsToRun(
412            ['gtest_color_test.py'],
413            '',
414            False,
415            available_configurations=self.fake_configurations),
416        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
417         []))
418
419  def testIgnoresNonTestFiles(self):
420    """Verifies that GetTestsToRun ignores non-test files in the filesystem."""
421
422    self.fake_os = FakeOs(FakePath(
423        current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)),
424        known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_nontest'),
425                     'test/']))
426    self.test_runner = run_tests_util.TestRunner(script_dir='.',
427                                                 injected_os=self.fake_os,
428                                                 injected_subprocess=None)
429    self.AssertResultsEqual(
430        self.test_runner.GetTestsToRun(
431            [],
432            '',
433            True,
434            available_configurations=self.fake_configurations),
435        ([], []))
436
437  def testWorksFromDifferentDir(self):
438    """Exercises GetTestsToRun from a directory different from run_test.py's."""
439
440    # Here we simulate an test script in directory /d/ called from the
441    # directory /a/b/c/.
442    self.fake_os = FakeOs(FakePath(
443        current_dir=os.path.abspath('/a/b/c'),
444        known_paths=[
445            '/a/b/c/',
446            AddExeExtension('/d/' + GTEST_DBG_DIR + '/gtest_unittest'),
447            AddExeExtension('/d/' + GTEST_OPT_DIR + '/gtest_unittest'),
448            '/d/test/gtest_color_test.py']))
449    self.fake_configurations = ['dbg', 'opt']
450    self.test_runner = run_tests_util.TestRunner(script_dir='/d/',
451                                                 injected_os=self.fake_os,
452                                                 injected_subprocess=None)
453    # A binary test.
454    self.AssertResultsEqual(
455        self.test_runner.GetTestsToRun(
456            ['gtest_unittest'],
457            '',
458            False,
459            available_configurations=self.fake_configurations),
460        ([],
461         [('/d/' + GTEST_DBG_DIR, '/d/' + GTEST_DBG_DIR + '/gtest_unittest')]))
462
463    # A Python test.
464    self.AssertResultsEqual(
465        self.test_runner.GetTestsToRun(
466            ['gtest_color_test.py'],
467            '',
468            False,
469            available_configurations=self.fake_configurations),
470        ([('/d/' + GTEST_DBG_DIR, '/d/test/gtest_color_test.py')], []))
471
472  def testNonTestBinary(self):
473    """Exercises GetTestsToRun with a non-test parameter."""
474
475    self.assert_(
476        not self.test_runner.GetTestsToRun(
477            ['gtest_unittest_not_really'],
478            '',
479            False,
480            available_configurations=self.fake_configurations))
481
482  def testNonExistingPythonTest(self):
483    """Exercises GetTestsToRun with a non-existent Python test parameter."""
484
485    self.assert_(
486        not self.test_runner.GetTestsToRun(
487            ['nonexistent_test.py'],
488            '',
489            False,
490            available_configurations=self.fake_configurations))
491
492  if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN:
493
494    def testDoesNotPickNonExeFilesOnWindows(self):
495      """Verifies that GetTestsToRun does not find _test files on Windows."""
496
497      self.fake_os = FakeOs(FakePath(
498          current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)),
499          known_paths=['/d/' + GTEST_DBG_DIR + '/gtest_test', 'test/']))
500      self.test_runner = run_tests_util.TestRunner(script_dir='.',
501                                                   injected_os=self.fake_os,
502                                                   injected_subprocess=None)
503      self.AssertResultsEqual(
504          self.test_runner.GetTestsToRun(
505              [],
506              '',
507              True,
508              available_configurations=self.fake_configurations),
509          ([], []))
510
511
512class RunTestsTest(unittest.TestCase):
513  """Exercises TestRunner.RunTests."""
514
515  def SpawnSuccess(self, unused_executable, unused_argv):
516    """Fakes test success by returning 0 as an exit code."""
517
518    self.num_spawn_calls += 1
519    return 0
520
521  def SpawnFailure(self, unused_executable, unused_argv):
522    """Fakes test success by returning 1 as an exit code."""
523
524    self.num_spawn_calls += 1
525    return 1
526
527  def setUp(self):
528    self.fake_os = FakeOs(FakePath(
529        current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)),
530        known_paths=[
531            AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'),
532            AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'),
533            'test/gtest_color_test.py']))
534    self.fake_configurations = ['dbg', 'opt']
535    self.test_runner = run_tests_util.TestRunner(
536        script_dir=os.path.dirname(__file__) or '.',
537        injected_os=self.fake_os,
538        injected_subprocess=None)
539    self.num_spawn_calls = 0  # A number of calls to spawn.
540
541  def testRunPythonTestSuccess(self):
542    """Exercises RunTests to handle a Python test success."""
543
544    self.fake_os.spawn_impl = self.SpawnSuccess
545    self.assertEqual(
546        self.test_runner.RunTests(
547            [(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
548            []),
549        0)
550    self.assertEqual(self.num_spawn_calls, 1)
551
552  def testRunBinaryTestSuccess(self):
553    """Exercises RunTests to handle a binary test success."""
554
555    self.fake_os.spawn_impl = self.SpawnSuccess
556    self.assertEqual(
557        self.test_runner.RunTests(
558            [],
559            [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]),
560        0)
561    self.assertEqual(self.num_spawn_calls, 1)
562
563  def testRunPythonTestFauilure(self):
564    """Exercises RunTests to handle a Python test failure."""
565
566    self.fake_os.spawn_impl = self.SpawnFailure
567    self.assertEqual(
568        self.test_runner.RunTests(
569            [(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
570            []),
571        1)
572    self.assertEqual(self.num_spawn_calls, 1)
573
574  def testRunBinaryTestFailure(self):
575    """Exercises RunTests to handle a binary test failure."""
576
577    self.fake_os.spawn_impl = self.SpawnFailure
578    self.assertEqual(
579        self.test_runner.RunTests(
580            [],
581            [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]),
582        1)
583    self.assertEqual(self.num_spawn_calls, 1)
584
585  def testCombinedTestSuccess(self):
586    """Exercises RunTests to handle a success of both Python and binary test."""
587
588    self.fake_os.spawn_impl = self.SpawnSuccess
589    self.assertEqual(
590        self.test_runner.RunTests(
591            [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')],
592            [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]),
593        0)
594    self.assertEqual(self.num_spawn_calls, 2)
595
596  def testCombinedTestSuccessAndFailure(self):
597    """Exercises RunTests to handle a success of both Python and binary test."""
598
599    def SpawnImpl(executable, argv):
600      self.num_spawn_calls += 1
601      # Simulates failure of a Python test and success of a binary test.
602      if '.py' in executable or '.py' in argv[0]:
603        return 1
604      else:
605        return 0
606
607    self.fake_os.spawn_impl = SpawnImpl
608    self.assertEqual(
609        self.test_runner.RunTests(
610            [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')],
611            [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]),
612        0)
613    self.assertEqual(self.num_spawn_calls, 2)
614
615
616class ParseArgsTest(unittest.TestCase):
617  """Exercises ParseArgs."""
618
619  def testNoOptions(self):
620    options, args = run_tests_util.ParseArgs('gtest', argv=['script.py'])
621    self.assertEqual(args, ['script.py'])
622    self.assert_(options.configurations is None)
623    self.assertFalse(options.built_configurations)
624
625  def testOptionC(self):
626    options, args = run_tests_util.ParseArgs(
627        'gtest', argv=['script.py', '-c', 'dbg'])
628    self.assertEqual(args, ['script.py'])
629    self.assertEqual(options.configurations, 'dbg')
630    self.assertFalse(options.built_configurations)
631
632  def testOptionA(self):
633    options, args = run_tests_util.ParseArgs('gtest', argv=['script.py', '-a'])
634    self.assertEqual(args, ['script.py'])
635    self.assertEqual(options.configurations, 'all')
636    self.assertFalse(options.built_configurations)
637
638  def testOptionB(self):
639    options, args = run_tests_util.ParseArgs('gtest', argv=['script.py', '-b'])
640    self.assertEqual(args, ['script.py'])
641    self.assert_(options.configurations is None)
642    self.assertTrue(options.built_configurations)
643
644  def testOptionCAndOptionB(self):
645    options, args = run_tests_util.ParseArgs(
646        'gtest', argv=['script.py', '-c', 'dbg', '-b'])
647    self.assertEqual(args, ['script.py'])
648    self.assertEqual(options.configurations, 'dbg')
649    self.assertTrue(options.built_configurations)
650
651  def testOptionH(self):
652    help_called = [False]
653
654    # Suppresses lint warning on unused arguments.  These arguments are
655    # required by optparse, even though they are unused.
656    # pylint: disable-msg=W0613
657    def VerifyHelp(option, opt, value, parser):
658      help_called[0] = True
659
660    # Verifies that -h causes the help callback to be called.
661    help_called[0] = False
662    _, args = run_tests_util.ParseArgs(
663        'gtest', argv=['script.py', '-h'], help_callback=VerifyHelp)
664    self.assertEqual(args, ['script.py'])
665    self.assertTrue(help_called[0])
666
667    # Verifies that --help causes the help callback to be called.
668    help_called[0] = False
669    _, args = run_tests_util.ParseArgs(
670        'gtest', argv=['script.py', '--help'], help_callback=VerifyHelp)
671    self.assertEqual(args, ['script.py'])
672    self.assertTrue(help_called[0])
673
674
675if __name__ == '__main__':
676  unittest.main()
677