15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2010 The Chromium Authors. All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""Unit tests for coverage_posix.py.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Run a single test with a command such as:
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ./coverage_posix_unittest.py CoveragePosixTest.testFindTestsAsArgs
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Waring that running a single test like that may interfere with the arg
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)parsing tests, since coverage_posix.py uses optparse.OptionParser()
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)which references globals.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import coverage_posix as coverage
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import tempfile
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import unittest
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CoveragePosixTest(unittest.TestCase):
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def setUp(self):
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.parseArgs()
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.sample_test_names = ['zippy_tests', '../base/base.gyp:base_unittests']
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def confirmSampleTestsArePresent(self, tests):
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Confirm the tests in self.sample_test_names are in some form in 'tests'.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    The Coverage object can munge them (e.g. add .exe to the end as needed.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Helper function for arg parsing, bundle file tests.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tests: the parsed tests from a Coverage object.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for simple_test_name in ('zippy_tests', 'base_unittests'):
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      found = False
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for item in tests:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if simple_test_name in item:
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          found = True
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertTrue(found)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for not_test_name in ('kablammo', 'not_a_unittest'):
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      found = False
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for item in tests:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not_test_name in item:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          found = True
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertFalse(found)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def parseArgs(self):
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Setup and process arg parsing."""
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.parser = coverage.CoverageOptionParser()
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (self.options, self.args) = self.parser.parse_args()
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.options.directory = '.'
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testSanity(self):
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Sanity check we're able to actually run the tests.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Simply creating a Coverage instance checks a few things (e.g. on
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Windows that the coverage tools can be found)."""
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c = coverage.Coverage(self.options, self.args)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testRunBasicProcess(self):
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Test a simple run of a subprocess."""
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c = coverage.Coverage(self.options, self.args)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for code in range(2):
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      retcode = c.Run([sys.executable, '-u', '-c',
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       'import sys; sys.exit(%d)' % code],
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      ignore_error=True)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.assertEqual(code, retcode)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testRunSlowProcess(self):
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Test program which prints slowly but doesn't hit our timeout.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Overall runtime is longer than the timeout but output lines
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    trickle in keeping things alive.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.options.timeout = 2.5
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c = coverage.Coverage(self.options, self.args)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    slowscript = ('import sys, time\n'
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  'for x in range(10):\n'
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  '  time.sleep(0.5)\n'
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  '  print "hi mom"\n'
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  'sys.exit(0)\n')
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    retcode = c.Run([sys.executable, '-u', '-c', slowscript])
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEqual(0, retcode)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testRunExcessivelySlowProcess(self):
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Test program which DOES hit our timeout.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Initial lines should print but quickly it takes too long and
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    should be killed.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.options.timeout = 2.5
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c = coverage.Coverage(self.options, self.args)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    slowscript = ('import time\n'
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  'for x in range(1,10):\n'
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  '  print "sleeping for %d" % x\n'
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  '  time.sleep(x)\n')
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertRaises(Exception,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      c.Run,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      [sys.executable, '-u', '-c', slowscript])
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testFindTestsAsArgs(self):
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Test finding of tests passed as args."""
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.args += '--'
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.args += self.sample_test_names
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c = coverage.Coverage(self.options, self.args)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c.FindTests()
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.confirmSampleTestsArePresent(c.tests)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testFindTestsFromBundleFile(self):
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Test finding of tests from a bundlefile."""
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (fd, filename) = tempfile.mkstemp()
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    f = os.fdopen(fd, 'w')
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    f.write(str(self.sample_test_names))
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    f.close()
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.options.bundles = filename
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c = coverage.Coverage(self.options, self.args)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c.FindTests()
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.confirmSampleTestsArePresent(c.tests)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    os.unlink(filename)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testExclusionList(self):
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Test the gtest_filter exclusion list."""
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c = coverage.Coverage(self.options, self.args)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertFalse(c.GtestFilter('doesnotexist_test'))
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fake_exclusions = { sys.platform: { 'foobar':
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        ('a','b'),
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        'doesnotexist_test':
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        ('Evil.Crash','Naughty.Test') } }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertFalse(c.GtestFilter('barfoo'))
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filter = c.GtestFilter('doesnotexist_test', fake_exclusions)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEquals('--gtest_filter=-Evil.Crash:-Naughty.Test', filter)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__':
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest.main()
143