diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h index 4a8f6e0a..93b755fb 100644 --- a/googletest/include/gtest/gtest.h +++ b/googletest/include/gtest/gtest.h @@ -687,6 +687,9 @@ class GTEST_API_ TestInfo { // Returns the line where this test is defined. int line() const { return location_.line; } + // Return true if this test should not be run because it's in another shard. + bool is_in_another_shard() const { return is_in_another_shard_; } + // Returns true if this test should run, that is if the test is not // disabled (or it is disabled but the also_run_disabled_tests flag has // been specified) and its full name matches the user-specified filter. @@ -707,10 +710,9 @@ class GTEST_API_ TestInfo { // Returns true iff this test will appear in the XML report. bool is_reportable() const { - // The XML report includes tests matching the filter. - // In the future, we may trim tests that are excluded because of - // sharding. - return matches_filter_; + // The XML report includes tests matching the filter, excluding those + // run in other shards. + return matches_filter_ && !is_in_another_shard_; } // Returns the result of the test. @@ -774,6 +776,7 @@ class GTEST_API_ TestInfo { bool is_disabled_; // True iff this test is disabled bool matches_filter_; // True if this test matches the // user-specified filter. + bool is_in_another_shard_; // Will be run in another shard. internal::TestFactoryBase* const factory_; // The factory that creates // the test object diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 723d905b..3435f9cb 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -4813,10 +4813,11 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && matches_filter; - const bool is_selected = is_runnable && - (shard_tests == IGNORE_SHARDING_PROTOCOL || - ShouldRunTestOnShard(total_shards, shard_index, - num_runnable_tests)); + const bool is_in_another_shard = + shard_tests != IGNORE_SHARDING_PROTOCOL && + !ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests); + test_info->is_in_another_shard_ = is_in_another_shard; + const bool is_selected = is_runnable && !is_in_another_shard; num_runnable_tests += is_runnable; num_selected_tests += is_selected; diff --git a/googletest/test/gtest_repeat_test.cc b/googletest/test/gtest_repeat_test.cc index b9e65e4c..31716043 100644 --- a/googletest/test/gtest_repeat_test.cc +++ b/googletest/test/gtest_repeat_test.cc @@ -67,7 +67,7 @@ namespace { // Used for verifying that global environment set-up and tear-down are -// inside the gtest_repeat loop. +// inside the --gtest_repeat loop. int g_environment_set_up_count = 0; int g_environment_tear_down_count = 0; diff --git a/googletest/test/gtest_uninitialized_test.py b/googletest/test/gtest_uninitialized_test.py index 41bc4810..574db77a 100755 --- a/googletest/test/gtest_uninitialized_test.py +++ b/googletest/test/gtest_uninitialized_test.py @@ -36,7 +36,6 @@ __author__ = 'wan@google.com (Zhanyong Wan)' import os import gtest_test_utils - COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_') @@ -57,8 +56,8 @@ def TestExitCodeAndOutput(command): # Verifies that 'command' exits with code 1. p = gtest_test_utils.Subprocess(command) - Assert(p.exited) - AssertEq(1, p.exit_code) + if p.exited and p.exit_code == 0: + Assert('IMPORTANT NOTICE' in p.output); Assert('InitGoogleTest' in p.output) diff --git a/googletest/test/gtest_uninitialized_test_.cc b/googletest/test/gtest_uninitialized_test_.cc index 44316987..502b0add 100644 --- a/googletest/test/gtest_uninitialized_test_.cc +++ b/googletest/test/gtest_uninitialized_test_.cc @@ -34,8 +34,8 @@ TEST(DummyTest, Dummy) { // This test doesn't verify anything. We just need it to create a // realistic stage for testing the behavior of Google Test when - // RUN_ALL_TESTS() is called without testing::InitGoogleTest() being - // called first. + // RUN_ALL_TESTS() is called without + // testing::InitGoogleTest() being called first. } int main() { diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index 53945622..a45927d0 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -34,9 +34,9 @@ #include "gtest/gtest.h" -// Verifies that the command line flag variables can be accessed -// in code once has been #included. -// Do not move it after other #includes. +// Verifies that the command line flag variables can be accessed in +// code once "gtest/gtest.h" has been +// #included. Do not move it after other gtest #includes. TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { bool dummy = testing::GTEST_FLAG(also_run_disabled_tests) || testing::GTEST_FLAG(break_on_failure) diff --git a/googletest/test/gtest_xml_output_unittest.py b/googletest/test/gtest_xml_output_unittest.py index 9f92f982..325ca131 100755 --- a/googletest/test/gtest_xml_output_unittest.py +++ b/googletest/test/gtest_xml_output_unittest.py @@ -31,8 +31,6 @@ """Unit test for the gtest_xml_output module""" -__author__ = 'eefacm@gmail.com (Sean Mcafee)' - import datetime import errno import os @@ -43,12 +41,16 @@ from xml.dom import minidom, Node import gtest_test_utils import gtest_xml_test_utils - GTEST_FILTER_FLAG = '--gtest_filter' GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' -GTEST_OUTPUT_FLAG = "--gtest_output" -GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" -GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_" +GTEST_OUTPUT_FLAG = '--gtest_output' +GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml' +GTEST_PROGRAM_NAME = 'gtest_xml_output_unittest_' + +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' +SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE' SUPPORTS_STACK_TRACES = False @@ -141,6 +143,19 @@ EXPECTED_FILTERED_TEST_XML = """ """ +EXPECTED_SHARDED_TEST_XML = """ + + + + + + + + + + +""" + EXPECTED_EMPTY_XML = """ @@ -182,7 +197,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): Runs a test program that generates an empty XML output, and checks if the timestamp attribute in the testsuites tag is valid. """ - actual = self._GetXmlOutput('gtest_no_test_unittest', [], 0) + actual = self._GetXmlOutput('gtest_no_test_unittest', [], {}, 0) date_time_str = actual.documentElement.getAttributeNode('timestamp').value # datetime.strptime() is only available in Python 2.5+ so we have to # parse the expected datetime manually. @@ -212,8 +227,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): 'gtest_no_test_unittest') try: os.remove(output_file) - except OSError: - e = sys.exc_info()[1] + except OSError, e: if e.errno != errno.ENOENT: raise @@ -263,7 +277,22 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED_TEST_XML, 0, extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG]) - def _GetXmlOutput(self, gtest_prog_name, extra_args, expected_exit_code): + def testShardedTestXmlOutput(self): + """Verifies XML output when run using multiple shards. + + Runs a test program that executes only one shard and verifies that tests + from other shards do not show up in the XML output. + """ + + self._TestXmlOutput( + GTEST_PROGRAM_NAME, + EXPECTED_SHARDED_TEST_XML, + 0, + extra_env={SHARD_INDEX_ENV_VAR: '0', + TOTAL_SHARDS_ENV_VAR: '10'}) + + def _GetXmlOutput(self, gtest_prog_name, extra_args, extra_env, + expected_exit_code): """ Returns the xml output generated by running the program gtest_prog_name. Furthermore, the program's exit code must be expected_exit_code. @@ -274,7 +303,11 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): command = ([gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] + extra_args) - p = gtest_test_utils.Subprocess(command) + environ_copy = os.environ.copy() + if extra_env: + environ_copy.update(extra_env) + p = gtest_test_utils.Subprocess(command, env=environ_copy) + if p.terminated_by_signal: self.assert_(False, '%s was killed by signal %d' % (gtest_prog_name, p.signal)) @@ -288,7 +321,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): return actual def _TestXmlOutput(self, gtest_prog_name, expected_xml, - expected_exit_code, extra_args=None): + expected_exit_code, extra_args=None, extra_env=None): """ Asserts that the XML document generated by running the program gtest_prog_name matches expected_xml, a string containing another @@ -297,7 +330,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): """ actual = self._GetXmlOutput(gtest_prog_name, extra_args or [], - expected_exit_code) + extra_env or {}, expected_exit_code) expected = minidom.parseString(expected_xml) self.NormalizeXml(actual.documentElement) self.AssertEquivalentNodes(expected.documentElement, diff --git a/googletest/test/gtest_xml_test_utils.py b/googletest/test/gtest_xml_test_utils.py index 341956b5..30c25d98 100755 --- a/googletest/test/gtest_xml_test_utils.py +++ b/googletest/test/gtest_xml_test_utils.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # Copyright 2006, Google Inc. # All rights reserved. # @@ -31,15 +29,12 @@ """Unit test utilities for gtest_xml_output""" -__author__ = 'eefacm@gmail.com (Sean Mcafee)' - +import os import re +import gtest_test_utils from xml.dom import minidom, Node -import gtest_test_utils - -GTEST_OUTPUT_FLAG = '--gtest_output' GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml' class GTestXMLTestCase(gtest_test_utils.TestCase): @@ -101,7 +96,7 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): self.assertEquals( len(expected_children), len(actual_children), 'number of child elements differ in element ' + actual_node.tagName) - for child_id, child in expected_children.items(): + for child_id, child in expected_children.iteritems(): self.assert_(child_id in actual_children, '<%s> is not in <%s> (in element %s)' % (child_id, actual_children, actual_node.tagName)) @@ -187,8 +182,8 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): # Replaces the source line information with a normalized form. cdata = re.sub(source_line_pat, '\\1*\n', child.nodeValue) # Removes the actual stack trace. - child.nodeValue = re.sub(r'\nStack trace:\n(.|\n)*', - '', cdata) + child.nodeValue = re.sub(r'Stack trace:\n(.|\n)*', + 'Stack trace:\n*', cdata) for child in element.childNodes: if child.nodeType == Node.ELEMENT_NODE: self.NormalizeXml(child)