class ExportFileTest(unittest.TestCase):
    def setUp(self):
        self._filesystem = FileSystem()
        self._temp_dir = str(self._filesystem.mkdtemp(suffix="exportfiles"))
        self._old_cwd = self._filesystem.getcwd()
        self._filesystem.chdir(self._temp_dir)
        self._filesystem.write_text_file(
            os.path.join(self._temp_dir, "sorted_file.exp.in"),
            _sorted_file_contents)
        self._filesystem.write_text_file(
            os.path.join(self._temp_dir, "non_sorted_file.exp.in"),
            _non_sorted_file_contents)
        self._filesystem.write_text_file(
            os.path.join(self._temp_dir, "parse_error_file.exp.in"),
            _parse_error_file_contents)

    def tearDown(self):
        self._filesystem.rmtree(self._temp_dir)
        self._filesystem.chdir(self._old_cwd)

    def test_sorted(self):
        """ Test sorted file. """

        file_path = os.path.join(self._temp_dir, "sorted_file.exp.in")
        error_handler = MockErrorHandler(handle_style_error)
        error_handler.errors = []
        error_handler.had_error = False
        checker = ExportFileChecker(file_path, error_handler)
        checker.check()
        self.assertFalse(error_handler.had_error)

    def test_non_sorted(self):
        """ Test non sorted file. """

        file_path = os.path.join(self._temp_dir, "non_sorted_file.exp.in")
        error_handler = MockErrorHandler(handle_style_error)
        error_handler.errors = []
        error_handler.had_error = False
        checker = ExportFileChecker(file_path, error_handler)
        checker.check()
        self.assertTrue(error_handler.had_error)
        self.assertEqual(
            error_handler.errors[0],
            (0, 'list/order', 5, file_path +
             " should be sorted, use Tools/Scripts/sort-export-file script"))

    def test_parse_error(self):
        """ Test parse error file. """

        file_path = os.path.join(self._temp_dir, "parse_error_file.exp.in")
        error_handler = MockErrorHandler(handle_style_error)
        error_handler.errors = []
        error_handler.had_error = False
        checker = ExportFileChecker(file_path, error_handler)
        checker.check()
        self.assertTrue(error_handler.had_error)
        self.assertEqual(
            error_handler.errors[0],
            (0, 'list/order', 5, "Parse error during processing " + file_path +
             ", use Tools/Scripts/sort-export-files for details"))
class TextFileReaderTest(LoggingTestCase):

    class MockProcessor(ProcessorBase):

        """A processor for test purposes.

        This processor simply records the parameters passed to its process()
        method for later checking by the unittest test methods.

        """

        def __init__(self):
            self.processed = []
            """The parameters passed for all calls to the process() method."""

        def should_process(self, file_path):
            return not file_path.endswith('should_not_process.txt')

        def process(self, lines, file_path, test_kwarg=None):
            self.processed.append((lines, file_path, test_kwarg))

    def setUp(self):
        LoggingTestCase.setUp(self)
        # FIXME: This should be a MockFileSystem once TextFileReader is moved entirely on top of FileSystem.
        self.filesystem = FileSystem()
        self._temp_dir = str(self.filesystem.mkdtemp())
        self._processor = TextFileReaderTest.MockProcessor()
        self._file_reader = TextFileReader(self.filesystem, self._processor)

    def tearDown(self):
        LoggingTestCase.tearDown(self)
        self.filesystem.rmtree(self._temp_dir)

    def _create_file(self, rel_path, text):
        """Create a file with given text and return the path to the file."""
        # FIXME: There are better/more secure APIs for creating tmp file paths.
        file_path = self.filesystem.join(self._temp_dir, rel_path)
        self.filesystem.write_text_file(file_path, text)
        return file_path

    def _passed_to_processor(self):
        """Return the parameters passed to MockProcessor.process()."""
        return self._processor.processed

    def _assert_file_reader(self, passed_to_processor, file_count):
        """Assert the state of the file reader."""
        self.assertEqual(passed_to_processor, self._passed_to_processor())
        self.assertEqual(file_count, self._file_reader.file_count)

    def test_process_file__does_not_exist(self):
        try:
            self._file_reader.process_file('does_not_exist.txt')
        except SystemExit, err:
            self.assertEqual(str(err), '1')
        else:
Esempio n. 3
0
class TextFileReaderTest(LoggingTestCase):

    class MockProcessor(ProcessorBase):

        """A processor for test purposes.

        This processor simply records the parameters passed to its process()
        method for later checking by the unittest test methods.

        """

        def __init__(self):
            self.processed = []
            """The parameters passed for all calls to the process() method."""

        def should_process(self, file_path):
            return not file_path.endswith('should_not_process.txt')

        def process(self, lines, file_path, test_kwarg=None):
            self.processed.append((lines, file_path, test_kwarg))

    def setUp(self):
        LoggingTestCase.setUp(self)
        # FIXME: This should be a MockFileSystem once TextFileReader is moved entirely on top of FileSystem.
        self.filesystem = FileSystem()
        self._temp_dir = str(self.filesystem.mkdtemp())
        self._processor = TextFileReaderTest.MockProcessor()
        self._file_reader = TextFileReader(self.filesystem, self._processor)

    def tearDown(self):
        LoggingTestCase.tearDown(self)
        self.filesystem.rmtree(self._temp_dir)

    def _create_file(self, rel_path, text):
        """Create a file with given text and return the path to the file."""
        # FIXME: There are better/more secure APIs for creating tmp file paths.
        file_path = self.filesystem.join(self._temp_dir, rel_path)
        self.filesystem.write_text_file(file_path, text)
        return file_path

    def _passed_to_processor(self):
        """Return the parameters passed to MockProcessor.process()."""
        return self._processor.processed

    def _assert_file_reader(self, passed_to_processor, file_count):
        """Assert the state of the file reader."""
        self.assertEqual(passed_to_processor, self._passed_to_processor())
        self.assertEqual(file_count, self._file_reader.file_count)

    def test_process_file__does_not_exist(self):
        try:
            self._file_reader.process_file('does_not_exist.txt')
        except SystemExit, err:
            self.assertEqual(str(err), '1')
        else:
class ExportFileTest(unittest.TestCase):

    def setUp(self):
        self._filesystem = FileSystem()
        self._temp_dir = str(self._filesystem.mkdtemp(suffix="exportfiles"))
        self._old_cwd = self._filesystem.getcwd()
        self._filesystem.chdir(self._temp_dir)
        self._filesystem.write_text_file(os.path.join(self._temp_dir, "sorted_file.exp.in"), _sorted_file_contents)
        self._filesystem.write_text_file(os.path.join(self._temp_dir, "non_sorted_file.exp.in"), _non_sorted_file_contents)
        self._filesystem.write_text_file(os.path.join(self._temp_dir, "parse_error_file.exp.in"), _parse_error_file_contents)

    def tearDown(self):
        self._filesystem.rmtree(self._temp_dir)
        self._filesystem.chdir(self._old_cwd)

    def test_sorted(self):
        """ Test sorted file. """

        file_path = os.path.join(self._temp_dir, "sorted_file.exp.in")
        error_handler = MockErrorHandler(handle_style_error)
        error_handler.errors = []
        error_handler.had_error = False
        checker = ExportFileChecker(file_path, error_handler)
        checker.check()
        self.assertFalse(error_handler.had_error)

    def test_non_sorted(self):
        """ Test non sorted file. """

        file_path = os.path.join(self._temp_dir, "non_sorted_file.exp.in")
        error_handler = MockErrorHandler(handle_style_error)
        error_handler.errors = []
        error_handler.had_error = False
        checker = ExportFileChecker(file_path, error_handler)
        checker.check()
        self.assertTrue(error_handler.had_error)
        self.assertEqual(error_handler.errors[0], (0, 'list/order', 5, file_path + " should be sorted, use Tools/Scripts/sort-export-file script"))

    def test_parse_error(self):
        """ Test parse error file. """

        file_path = os.path.join(self._temp_dir, "parse_error_file.exp.in")
        error_handler = MockErrorHandler(handle_style_error)
        error_handler.errors = []
        error_handler.had_error = False
        checker = ExportFileChecker(file_path, error_handler)
        checker.check()
        self.assertTrue(error_handler.had_error)
        self.assertEqual(error_handler.errors[0], (0, 'list/order', 5, "Parse error during processing " + file_path + ", use Tools/Scripts/sort-export-files for details"))
Esempio n. 5
0
class CommitMessageForThisCommitTest(unittest.TestCase):
    expected_commit_message = u"""Unreviewed build fix to un-break webkit-patch land.

Tools: 

Move commit_message_for_this_commit from scm to checkout
https://bugs.webkit.org/show_bug.cgi?id=36629

* Scripts/webkitpy/common/checkout/api.py: import scm.CommitMessage

LayoutTests: 

Second part of this complicated change by me, Tor Arne Vestb\u00f8!

* Path/To/Complicated/File: Added.
"""

    def setUp(self):
        # FIXME: This should not need to touch the filesystem, however
        # ChangeLog is difficult to mock at current.
        self.filesystem = FileSystem()
        self.temp_dir = str(self.filesystem.mkdtemp(suffix="changelogs"))
        self.old_cwd = self.filesystem.getcwd()
        self.filesystem.chdir(self.temp_dir)

        # Trick commit-log-editor into thinking we're in a Subversion working copy so it won't
        # complain about not being able to figure out what SCM is in use.
        # FIXME: VCSTools.pm is no longer so easily fooled.  It logs because "svn info" doesn't
        # treat a bare .svn directory being part of an svn checkout.
        self.filesystem.maybe_make_directory(".svn")

        self.changelogs = map(self.filesystem.abspath, (self.filesystem.join("Tools", "ChangeLog"), self.filesystem.join("LayoutTests", "ChangeLog")))
        for path, contents in zip(self.changelogs, (_changelog1, _changelog2)):
            self.filesystem.maybe_make_directory(self.filesystem.dirname(path))
            self.filesystem.write_text_file(path, contents)

    def tearDown(self):
        self.filesystem.rmtree(self.temp_dir)
        self.filesystem.chdir(self.old_cwd)

    def test_commit_message_for_this_commit(self):
        executive = Executive()

        def mock_run(*args, **kwargs):
            # Note that we use a real Executive here, not a MockExecutive, so we can test that we're
            # invoking commit-log-editor correctly.
            env = os.environ.copy()
            env['CHANGE_LOG_EMAIL_ADDRESS'] = '*****@*****.**'
            kwargs['env'] = env
            return executive.run_command(*args, **kwargs)

        detector = SCMDetector(self.filesystem, executive)
        real_scm = detector.detect_scm_system(self.old_cwd)

        mock_scm = MockSCM()
        mock_scm.run = mock_run
        mock_scm.script_path = real_scm.script_path

        checkout = Checkout(mock_scm)
        checkout.modified_changelogs = lambda git_commit, changed_files=None: self.changelogs
        commit_message = checkout.commit_message_for_this_commit(git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertMultiLineEqual(commit_message.message(), self.expected_commit_message)
Esempio n. 6
0
class CommitMessageForThisCommitTest(unittest.TestCase):
    expected_commit_message = u"""Unreviewed build fix to un-break webkit-patch land.

Tools: 

Move commit_message_for_this_commit from scm to checkout
https://bugs.webkit.org/show_bug.cgi?id=36629

* Scripts/webkitpy/common/checkout/api.py: import scm.CommitMessage

LayoutTests: 

Second part of this complicated change by me, Tor Arne Vestb\u00f8!

* Path/To/Complicated/File: Added.
"""

    def setUp(self):
        # FIXME: This should not need to touch the filesystem, however
        # ChangeLog is difficult to mock at current.
        self.filesystem = FileSystem()
        self.temp_dir = str(self.filesystem.mkdtemp(suffix="changelogs"))
        self.old_cwd = self.filesystem.getcwd()
        self.filesystem.chdir(self.temp_dir)

        # Trick commit-log-editor into thinking we're in a Subversion working copy so it won't
        # complain about not being able to figure out what SCM is in use.
        # FIXME: VCSTools.pm is no longer so easily fooled.  It logs because "svn info" doesn't
        # treat a bare .svn directory being part of an svn checkout.
        self.filesystem.maybe_make_directory(".svn")

        self.changelogs = map(self.filesystem.abspath, (self.filesystem.join("Tools", "ChangeLog"), self.filesystem.join("LayoutTests", "ChangeLog")))
        for path, contents in zip(self.changelogs, (_changelog1, _changelog2)):
            self.filesystem.maybe_make_directory(self.filesystem.dirname(path))
            self.filesystem.write_text_file(path, contents)

    def tearDown(self):
        self.filesystem.rmtree(self.temp_dir)
        self.filesystem.chdir(self.old_cwd)

    def test_commit_message_for_this_commit(self):
        executive = Executive()

        def mock_run(*args, **kwargs):
            # Note that we use a real Executive here, not a MockExecutive, so we can test that we're
            # invoking commit-log-editor correctly.
            env = os.environ.copy()
            env['CHANGE_LOG_EMAIL_ADDRESS'] = '*****@*****.**'
            kwargs['env'] = env
            return executive.run_command(*args, **kwargs)

        detector = SCMDetector(self.filesystem, executive)
        real_scm = detector.detect_scm_system(self.old_cwd)

        mock_scm = MockSCM()
        mock_scm.run = mock_run
        mock_scm.script_path = real_scm.script_path

        checkout = Checkout(mock_scm)
        checkout.modified_changelogs = lambda git_commit, changed_files=None: self.changelogs
        commit_message = checkout.commit_message_for_this_commit(git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertEqual(commit_message.message(), self.expected_commit_message)
class CommitMessageForThisCommitTest(unittest.TestCase):
    def setUp(self):
        # FIXME: This should not need to touch the filesystem, however
        # ChangeLog is difficult to mock at current.
        self.filesystem = FileSystem()
        self.temp_dir = str(self.filesystem.mkdtemp(suffix="changelogs"))
        self.old_cwd = self.filesystem.getcwd()
        self.filesystem.chdir(self.temp_dir)
        self.webkit_base = WebKitFinder(self.filesystem).webkit_base()

        # Trick commit-log-editor into thinking we're in a Subversion working copy so it won't
        # complain about not being able to figure out what SCM is in use.
        # FIXME: VCSTools.pm is no longer so easily fooled.  It logs because "svn info" doesn't
        # treat a bare .svn directory being part of an svn checkout.
        self.filesystem.maybe_make_directory(".svn")

    def mock_changelog(self, changelogs):
        for path, contents in zip(self.changelog_paths, changelogs):
            self.filesystem.maybe_make_directory(self.filesystem.dirname(path))
            self.filesystem.write_text_file(path, contents)

    def tearDown(self):
        self.filesystem.rmtree(self.temp_dir)
        self.filesystem.chdir(self.old_cwd)

    def mock_checkout_for_test(self):
        executive = Executive()

        def mock_run(*args, **kwargs):
            # Note that we use a real Executive here, not a MockExecutive, so we can test that we're
            # invoking commit-log-editor correctly.
            env = os.environ.copy()
            env['CHANGE_LOG_EMAIL_ADDRESS'] = '*****@*****.**'
            kwargs['env'] = env
            return executive.run_command(*args, **kwargs)

        detector = SCMDetector(self.filesystem, executive)
        real_scm = detector.detect_scm_system(self.webkit_base)

        mock_scm = MockSCM()
        mock_scm.run = mock_run

        real_checkout = Checkout(real_scm)
        checkout = Checkout(mock_scm)
        checkout.script_path = real_checkout.script_path
        checkout.modified_changelogs = lambda git_commit, changed_files=None: self.changelog_paths

        return checkout

    def test_commit_message_for_unreviewed_changelogs_with_different_messages(
            self):
        expected_commit_message = u"""Unreviewed build fix to un-break webkit-patch land.

Tools:

Move commit_message_for_this_commit from scm to checkout
https://bugs.webkit.org/show_bug.cgi?id=36629

* Scripts/webkitpy/common/checkout/api.py: import scm.CommitMessage

LayoutTests:

Second part of this complicated change by me, Tor Arne Vestb\u00f8!

* Path/To/Complicated/File: Added.
"""

        self.changelog_paths = map(
            self.filesystem.abspath,
            (self.filesystem.join("Tools", "ChangeLog"),
             self.filesystem.join("LayoutTests", "ChangeLog")))

        self.mock_changelog((_changelog1, _changelog2))
        checkout = self.mock_checkout_for_test()
        commit_message = checkout.commit_message_for_this_commit(
            git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertMultiLineEqual(commit_message.message(),
                                  expected_commit_message)

    def test_commit_message_for_one_reviewed_changelog(self):
        expected_commit_message = u"""SECTORDER_FLAGS should be defined in target's xcconfig file, not Base.xcconfig
<http://webkit.org/b/135006>

Patch by David Kilzer <*****@*****.**> on 2014-07-17
Reviewed by Darin Adler.

* WebKit.xcodeproj/project.pbxproj: Remove references to unused
WebKit.xcconfig file.
"""

        self.changelog_paths = map(
            self.filesystem.abspath,
            [self.filesystem.join("Source/WebKit", "ChangeLog")])

        self.mock_changelog([_changelog3])
        checkout = self.mock_checkout_for_test()
        commit_message = checkout.commit_message_for_this_commit(
            git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertMultiLineEqual(commit_message.message(),
                                  expected_commit_message)

    def test_commit_message_for_changelogs_with_same_messages(self):
        expected_commit_message = u"""SECTORDER_FLAGS should be defined in target's xcconfig file, not Base.xcconfig
<http://webkit.org/b/135006>

Patch by David Kilzer <*****@*****.**> on 2014-07-17
Reviewed by Darin Adler.

Source/WebKit:

* WebKit.xcodeproj/project.pbxproj: Remove references to unused
WebKit.xcconfig file.

LayoutTests:

* Path/To/Complicated/File: Added.
"""

        self.changelog_paths = map(
            self.filesystem.abspath,
            (self.filesystem.join("Source/WebKit", "ChangeLog"),
             self.filesystem.join("LayoutTests", "ChangeLog")))

        self.mock_changelog((_changelog3, _changelog4))
        checkout = self.mock_checkout_for_test()
        commit_message = checkout.commit_message_for_this_commit(
            git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertMultiLineEqual(commit_message.message(),
                                  expected_commit_message)

    def test_commit_message_for_changelogs_with_different_messages(self):
        expected_commit_message = u"""SECTORDER_FLAGS should be defined in target's xcconfig file, not Base.xcconfig
<http://webkit.org/b/135006>

Patch by David Kilzer <*****@*****.**> on 2014-07-17
Reviewed by Darin Adler.

Source/WebKit:

* WebKit.xcodeproj/project.pbxproj: Remove references to unused
WebKit.xcconfig file.

LayoutTests:

Filler change.

* Path/To/Complicated/File: Added.
"""

        self.changelog_paths = map(
            self.filesystem.abspath,
            (self.filesystem.join("Source/WebKit", "ChangeLog"),
             self.filesystem.join("LayoutTests", "ChangeLog")))

        self.mock_changelog((_changelog3, _changelog5))
        checkout = self.mock_checkout_for_test()
        commit_message = checkout.commit_message_for_this_commit(
            git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertMultiLineEqual(commit_message.message(),
                                  expected_commit_message)

    def test_commit_message_for_one_rollout_changelog(self):
        expected_commit_message = u"""Rolling out r170340 and r170339.

Changeset r170339 broke the Apple Windows Debug and Release builds.

Reverted changesets:

"[Win] Build fix after r134209"
http://trac.webkit.org/changeset/170340

"[Win] Clean up and refactor WinLauncher"
https://bugs.webkit.org/show_bug.cgi?id=134209
http://trac.webkit.org/changeset/170339

Patch by Daniel Bates <*****@*****.**> on 2014-06-23
"""

        self.changelog_paths = map(
            self.filesystem.abspath,
            [self.filesystem.join("Tools", "ChangeLog")])

        self.mock_changelog([_changelog6])
        checkout = self.mock_checkout_for_test()
        commit_message = checkout.commit_message_for_this_commit(
            git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertMultiLineEqual(commit_message.message(),
                                  expected_commit_message)

    def test_commit_message_for_rollout_changelogs_with_different_directories(
            self):
        expected_commit_message = u"""Rolling out r170340 and r170339.

Changeset r170339 broke the Apple Windows Debug and Release builds.

Reverted changesets:

"[Win] Build fix after r134209"
http://trac.webkit.org/changeset/170340

"[Win] Clean up and refactor WinLauncher"
https://bugs.webkit.org/show_bug.cgi?id=134209
http://trac.webkit.org/changeset/170339

Patch by Daniel Bates <*****@*****.**> on 2014-06-23
"""

        self.changelog_paths = map(
            self.filesystem.abspath,
            (self.filesystem.join("Tools", "ChangeLog"),
             self.filesystem.join("Source/WebCore", "ChangeLog")))

        self.mock_changelog((_changelog6, _changelog6))
        checkout = self.mock_checkout_for_test()
        commit_message = checkout.commit_message_for_this_commit(
            git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertMultiLineEqual(commit_message.message(),
                                  expected_commit_message)
class SCMTestBase(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(SCMTestBase, self).__init__(*args, **kwargs)
        self.scm = None
        self.executive = None
        self.fs = None
        self.original_cwd = None

    def setUp(self):
        self.executive = Executive()
        self.fs = FileSystem()
        self.original_cwd = self.fs.getcwd()

    def tearDown(self):
        self._chdir(self.original_cwd)

    def _join(self, *comps):
        return self.fs.join(*comps)

    def _chdir(self, path):
        self.fs.chdir(path)

    def _mkdir(self, path):
        assert not self.fs.exists(path)
        self.fs.maybe_make_directory(path)

    def _mkdtemp(self, **kwargs):
        return str(self.fs.mkdtemp(**kwargs))

    def _remove(self, path):
        self.fs.remove(path)

    def _rmtree(self, path):
        self.fs.rmtree(path)

    def _run(self, *args, **kwargs):
        return self.executive.run_command(*args, **kwargs)

    def _run_silent(self, args, **kwargs):
        self.executive.run_and_throw_if_fail(args, quiet=True, **kwargs)

    def _write_text_file(self, path, contents):
        self.fs.write_text_file(path, contents)

    def _write_binary_file(self, path, contents):
        self.fs.write_binary_file(path, contents)

    def _make_diff(self, command, *args):
        # We use this wrapper to disable output decoding. diffs should be treated as
        # binary files since they may include text files of multiple differnet encodings.
        return self._run([command, "diff"] + list(args), decode_output=False)

    def _svn_diff(self, *args):
        return self._make_diff("svn", *args)

    def _git_diff(self, *args):
        return self._make_diff("git", *args)

    def _svn_add(self, path):
        self._run(["svn", "add", path])

    def _svn_commit(self, message):
        self._run(["svn", "commit", "--quiet", "--message", message])

    # This is a hot function since it's invoked by unittest before calling each test_ method in SVNTest and
    # GitTest. We create a mock SVN repo once and then perform an SVN checkout from a filesystem copy of
    # it since it's expensive to create the mock repo.
    def _set_up_svn_checkout(self):
        global cached_svn_repo_path
        global original_cwd
        if not cached_svn_repo_path:
            cached_svn_repo_path = self._set_up_svn_repo()
            original_cwd = self.original_cwd

        self.temp_directory = self._mkdtemp(suffix="svn_test")
        self.svn_repo_path = self._join(self.temp_directory, "repo")
        self.svn_repo_url = "file://%s" % self.svn_repo_path
        self.svn_checkout_path = self._join(self.temp_directory, "checkout")
        shutil.copytree(cached_svn_repo_path, self.svn_repo_path)
        self._run(["svn", "checkout", "--quiet", self.svn_repo_url + "/trunk", self.svn_checkout_path])

    def _set_up_svn_repo(self):
        svn_repo_path = self._mkdtemp(suffix="svn_test_repo")
        svn_repo_url = "file://%s" % svn_repo_path  # Not sure this will work on windows
        # git svn complains if we don't pass --pre-1.5-compatible, not sure why:
        # Expected FS format '2'; found format '3' at /usr/local/libexec/git-core//git-svn line 1477
        self._run(["svnadmin", "create", "--pre-1.5-compatible", svn_repo_path])

        # Create a test svn checkout
        svn_checkout_path = self._mkdtemp(suffix="svn_test_checkout")
        self._run(["svn", "checkout", "--quiet", svn_repo_url, svn_checkout_path])

        # Create and checkout a trunk dir to match the standard svn configuration to match git-svn's expectations
        self._chdir(svn_checkout_path)
        self._mkdir("trunk")
        self._svn_add("trunk")
        # We can add tags and branches as well if we ever need to test those.
        self._svn_commit("add trunk")

        self._rmtree(svn_checkout_path)

        self._set_up_svn_test_commits(svn_repo_url + "/trunk")
        return svn_repo_path

    def _set_up_svn_test_commits(self, svn_repo_url):
        svn_checkout_path = self._mkdtemp(suffix="svn_test_checkout")
        self._run(["svn", "checkout", "--quiet", svn_repo_url, svn_checkout_path])

        # Add some test commits
        self._chdir(svn_checkout_path)

        self._write_text_file("test_file", "test1")
        self._svn_add("test_file")
        self._svn_commit("initial commit")

        self._write_text_file("test_file", "test1test2")
        # This used to be the last commit, but doing so broke
        # GitTest.test_apply_git_patch which use the inverse diff of the last commit.
        # svn-apply fails to remove directories in Git, see:
        # https://bugs.webkit.org/show_bug.cgi?id=34871
        self._mkdir("test_dir")
        # Slash should always be the right path separator since we use cygwin on Windows.
        test_file3_path = "test_dir/test_file3"
        self._write_text_file(test_file3_path, "third file")
        self._svn_add("test_dir")
        self._svn_commit("second commit")

        self._write_text_file("test_file", "test1test2test3\n")
        self._write_text_file("test_file2", "second file")
        self._svn_add("test_file2")
        self._svn_commit("third commit")

        # This 4th commit is used to make sure that our patch file handling
        # code correctly treats patches as binary and does not attempt to
        # decode them assuming they're utf-8.
        self._write_binary_file("test_file", u"latin1 test: \u00A0\n".encode("latin-1"))
        self._write_binary_file("test_file2", u"utf-8 test: \u00A0\n".encode("utf-8"))
        self._svn_commit("fourth commit")

        # svn does not seem to update after commit as I would expect.
        self._run(["svn", "update"])
        self._rmtree(svn_checkout_path)

    def _tear_down_svn_checkout(self):
        self._rmtree(self.temp_directory)

    def _shared_test_add_recursively(self):
        self._mkdir("added_dir")
        self._write_text_file("added_dir/added_file", "new stuff")
        self.scm.add("added_dir/added_file")
        self.assertIn("added_dir/added_file", self.scm._added_files())

    def _shared_test_delete_recursively(self):
        self._mkdir("added_dir")
        self._write_text_file("added_dir/added_file", "new stuff")
        self.scm.add("added_dir/added_file")
        self.assertIn("added_dir/added_file", self.scm._added_files())
        self.scm.delete("added_dir/added_file")
        self.assertNotIn("added_dir", self.scm._added_files())

    def _shared_test_delete_recursively_or_not(self):
        self._mkdir("added_dir")
        self._write_text_file("added_dir/added_file", "new stuff")
        self._write_text_file("added_dir/another_added_file", "more new stuff")
        self.scm.add("added_dir/added_file")
        self.scm.add("added_dir/another_added_file")
        self.assertIn("added_dir/added_file", self.scm._added_files())
        self.assertIn("added_dir/another_added_file", self.scm._added_files())
        self.scm.delete("added_dir/added_file")
        self.assertIn("added_dir/another_added_file", self.scm._added_files())

    def _shared_test_exists(self, scm, commit_function):
        self._chdir(scm.checkout_root)
        self.assertFalse(scm.exists("foo.txt"))
        self._write_text_file("foo.txt", "some stuff")
        self.assertFalse(scm.exists("foo.txt"))
        scm.add("foo.txt")
        commit_function("adding foo")
        self.assertTrue(scm.exists("foo.txt"))
        scm.delete("foo.txt")
        commit_function("deleting foo")
        self.assertFalse(scm.exists("foo.txt"))

    def _shared_test_move(self):
        self._write_text_file("added_file", "new stuff")
        self.scm.add("added_file")
        self.scm.move("added_file", "moved_file")
        self.assertIn("moved_file", self.scm._added_files())

    def _shared_test_move_recursive(self):
        self._mkdir("added_dir")
        self._write_text_file("added_dir/added_file", "new stuff")
        self._write_text_file("added_dir/another_added_file", "more new stuff")
        self.scm.add("added_dir")
        self.scm.move("added_dir", "moved_dir")
        self.assertIn("moved_dir/added_file", self.scm._added_files())
        self.assertIn("moved_dir/another_added_file", self.scm._added_files())
Esempio n. 9
0
class TextFileReaderTest(LoggingTestCase):
    class MockProcessor(ProcessorBase):
        """A processor for test purposes.

        This processor simply records the parameters passed to its process()
        method for later checking by the unittest test methods.

        """
        def __init__(self):
            self.processed = []
            """The parameters passed for all calls to the process() method."""

        def should_process(self, file_path):
            return not file_path.endswith('should_not_process.txt')

        def process(self, lines, file_path, test_kwarg=None):
            self.processed.append((lines, file_path, test_kwarg))

    def setUp(self):
        LoggingTestCase.setUp(self)
        # FIXME: This should be a MockFileSystem once TextFileReader is moved entirely on top of FileSystem.
        self.filesystem = FileSystem()
        self._temp_dir = str(self.filesystem.mkdtemp())
        self._processor = TextFileReaderTest.MockProcessor()
        self._file_reader = TextFileReader(self.filesystem, self._processor)

    def tearDown(self):
        LoggingTestCase.tearDown(self)
        self.filesystem.rmtree(self._temp_dir)

    def _create_file(self, rel_path, text):
        """Create a file with given text and return the path to the file."""
        # FIXME: There are better/more secure APIs for creating tmp file paths.
        file_path = self.filesystem.join(self._temp_dir, rel_path)
        self.filesystem.write_text_file(file_path, text)
        return file_path

    def _passed_to_processor(self):
        """Return the parameters passed to MockProcessor.process()."""
        return self._processor.processed

    def _assert_file_reader(self, passed_to_processor, file_count):
        """Assert the state of the file reader."""
        self.assertEqual(passed_to_processor, self._passed_to_processor())
        self.assertEqual(file_count, self._file_reader.file_count)

    def test_process_file__does_not_exist(self):
        try:
            self._file_reader.process_file('does_not_exist.txt')
        except SystemExit as err:
            self.assertEqual(str(err), '1')
        else:
            self.fail('No Exception raised.')
        self._assert_file_reader([], 1)
        self.assertLog(["ERROR: File does not exist: 'does_not_exist.txt'\n"])

    def test_process_file__is_dir(self):
        temp_dir = self.filesystem.join(self._temp_dir, 'test_dir')
        self.filesystem.maybe_make_directory(temp_dir)

        self._file_reader.process_file(temp_dir)

        # Because the log message below contains exception text, it is
        # possible that the text varies across platforms.  For this reason,
        # we check only the portion of the log message that we control,
        # namely the text at the beginning.
        log_messages = self.logMessages()
        # We remove the message we are looking at to prevent the tearDown()
        # from raising an exception when it asserts that no log messages
        # remain.
        message = log_messages.pop()

        self.assertTrue(
            message.startswith(
                "WARNING: Could not read file. Skipping: '%s'\n  " % temp_dir))

        self._assert_file_reader([], 1)

    def test_process_file__should_not_process(self):
        file_path = self._create_file('should_not_process.txt', 'contents')

        self._file_reader.process_file(file_path)
        self._assert_file_reader([], 1)

    def test_process_file__multiple_lines(self):
        file_path = self._create_file('foo.txt', 'line one\r\nline two\n')

        self._file_reader.process_file(file_path)
        processed = [(['line one\r', 'line two', ''], file_path, None)]
        self._assert_file_reader(processed, 1)

    def test_process_file__file_stdin(self):
        file_path = self._create_file('-', 'file contents')

        self._file_reader.process_file(file_path=file_path, test_kwarg='foo')
        processed = [(['file contents'], file_path, 'foo')]
        self._assert_file_reader(processed, 1)

    def test_process_file__with_kwarg(self):
        file_path = self._create_file('foo.txt', 'file contents')

        self._file_reader.process_file(file_path=file_path, test_kwarg='foo')
        processed = [(['file contents'], file_path, 'foo')]
        self._assert_file_reader(processed, 1)

    def test_process_paths(self):
        # We test a list of paths that contains both a file and a directory.
        dir = self.filesystem.join(self._temp_dir, 'foo_dir')
        self.filesystem.maybe_make_directory(dir)

        file_path1 = self._create_file('file1.txt', 'foo')

        rel_path = self.filesystem.join('foo_dir', 'file2.txt')
        file_path2 = self._create_file(rel_path, 'bar')

        self._file_reader.process_paths([dir, file_path1])
        processed = [(['bar'], file_path2, None), (['foo'], file_path1, None)]
        self._assert_file_reader(processed, 2)

    def test_count_delete_only_file(self):
        self._file_reader.count_delete_only_file()
        delete_only_file_count = self._file_reader.delete_only_file_count
        self.assertEqual(delete_only_file_count, 1)
class SCMTestBase(unittest.TestCase):

    def __init__(self, *args, **kwargs):
        super(SCMTestBase, self).__init__(*args, **kwargs)
        self.scm = None
        self.executive = None
        self.fs = None
        self.original_cwd = None

    def setUp(self):
        self.executive = Executive()
        self.fs = FileSystem()
        self.original_cwd = self.fs.getcwd()

    def tearDown(self):
        self._chdir(self.original_cwd)

    def _join(self, *comps):
        return self.fs.join(*comps)

    def _chdir(self, path):
        self.fs.chdir(path)

    def _mkdir(self, path):
        assert not self.fs.exists(path)
        self.fs.maybe_make_directory(path)

    def _mkdtemp(self, **kwargs):
        return str(self.fs.mkdtemp(**kwargs))

    def _remove(self, path):
        self.fs.remove(path)

    def _rmtree(self, path):
        self.fs.rmtree(path)

    def _run(self, *args, **kwargs):
        return self.executive.run_command(*args, **kwargs)

    def _run_silent(self, args, **kwargs):
        self.executive.run_command(args, **kwargs)

    def _write_text_file(self, path, contents):
        self.fs.write_text_file(path, contents)

    def _write_binary_file(self, path, contents):
        self.fs.write_binary_file(path, contents)

    def _make_diff(self, command, *args):
        # We use this wrapper to disable output decoding. diffs should be treated as
        # binary files since they may include text files of multiple differnet encodings.
        return self._run([command, "diff"] + list(args), decode_output=False)

    def _git_diff(self, *args):
        return self._make_diff("git", *args)

    def _shared_test_add_recursively(self):
        self._mkdir("added_dir")
        self._write_text_file("added_dir/added_file", "new stuff")
        self.scm.add("added_dir/added_file")
        self.assertIn("added_dir/added_file", self.scm._added_files())

    def _shared_test_delete_recursively(self):
        self._mkdir("added_dir")
        self._write_text_file("added_dir/added_file", "new stuff")
        self.scm.add("added_dir/added_file")
        self.assertIn("added_dir/added_file", self.scm._added_files())
        self.scm.delete("added_dir/added_file")
        self.assertNotIn("added_dir", self.scm._added_files())

    def _shared_test_delete_recursively_or_not(self):
        self._mkdir("added_dir")
        self._write_text_file("added_dir/added_file", "new stuff")
        self._write_text_file("added_dir/another_added_file", "more new stuff")
        self.scm.add("added_dir/added_file")
        self.scm.add("added_dir/another_added_file")
        self.assertIn("added_dir/added_file", self.scm._added_files())
        self.assertIn("added_dir/another_added_file", self.scm._added_files())
        self.scm.delete("added_dir/added_file")
        self.assertIn("added_dir/another_added_file", self.scm._added_files())

    def _shared_test_exists(self, scm, commit_function):
        self._chdir(scm.checkout_root)
        self.assertFalse(scm.exists('foo.txt'))
        self._write_text_file('foo.txt', 'some stuff')
        self.assertFalse(scm.exists('foo.txt'))
        scm.add('foo.txt')
        commit_function('adding foo')
        self.assertTrue(scm.exists('foo.txt'))
        scm.delete('foo.txt')
        commit_function('deleting foo')
        self.assertFalse(scm.exists('foo.txt'))

    def _shared_test_move(self):
        self._write_text_file('added_file', 'new stuff')
        self.scm.add('added_file')
        self.scm.move('added_file', 'moved_file')
        self.assertIn('moved_file', self.scm._added_files())

    def _shared_test_move_recursive(self):
        self._mkdir("added_dir")
        self._write_text_file('added_dir/added_file', 'new stuff')
        self._write_text_file('added_dir/another_added_file', 'more new stuff')
        self.scm.add('added_dir')
        self.scm.move('added_dir', 'moved_dir')
        self.assertIn('moved_dir/added_file', self.scm._added_files())
        self.assertIn('moved_dir/another_added_file', self.scm._added_files())
Esempio n. 11
0
class SCMTestBase(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(SCMTestBase, self).__init__(*args, **kwargs)
        self.scm = None
        self.executive = None
        self.fs = None
        self.original_cwd = None

    def setUp(self):
        self.executive = Executive()
        self.fs = FileSystem()
        self.original_cwd = self.fs.getcwd()

    def tearDown(self):
        self._chdir(self.original_cwd)

    def _join(self, *comps):
        return self.fs.join(*comps)

    def _chdir(self, path):
        self.fs.chdir(path)

    def _mkdir(self, path):
        assert not self.fs.exists(path)
        self.fs.maybe_make_directory(path)

    def _mkdtemp(self, **kwargs):
        return str(self.fs.mkdtemp(**kwargs))

    def _remove(self, path):
        self.fs.remove(path)

    def _rmtree(self, path):
        self.fs.rmtree(path)

    def _run(self, *args, **kwargs):
        return self.executive.run_command(*args, **kwargs)

    def _run_silent(self, args, **kwargs):
        self.executive.run_and_throw_if_fail(args, quiet=True, **kwargs)

    def _write_text_file(self, path, contents):
        self.fs.write_text_file(path, contents)

    def _write_binary_file(self, path, contents):
        self.fs.write_binary_file(path, contents)

    def _make_diff(self, command, *args):
        # We use this wrapper to disable output decoding. diffs should be treated as
        # binary files since they may include text files of multiple differnet encodings.
        return self._run([command, "diff"] + list(args), decode_output=False)

    def _svn_diff(self, *args):
        return self._make_diff("svn", *args)

    def _git_diff(self, *args):
        return self._make_diff("git", *args)

    def _svn_add(self, path):
        self._run(["svn", "add", path])

    def _svn_commit(self, message):
        self._run(["svn", "commit", "--quiet", "--message", message])

    # This is a hot function since it's invoked by unittest before calling each test_ method in SVNTest and
    # GitTest. We create a mock SVN repo once and then perform an SVN checkout from a filesystem copy of
    # it since it's expensive to create the mock repo.
    def _set_up_svn_checkout(self):
        global cached_svn_repo_path
        global original_cwd
        if not cached_svn_repo_path:
            cached_svn_repo_path = self._set_up_svn_repo()
            original_cwd = self.original_cwd

        self.temp_directory = self._mkdtemp(suffix="svn_test")
        self.svn_repo_path = self._join(self.temp_directory, "repo")
        self.svn_repo_url = "file://%s" % self.svn_repo_path
        self.svn_checkout_path = self._join(self.temp_directory, "checkout")
        shutil.copytree(cached_svn_repo_path, self.svn_repo_path)
        self._run([
            'svn', 'checkout', '--quiet', self.svn_repo_url + "/trunk",
            self.svn_checkout_path
        ])

    def _set_up_svn_repo(self):
        svn_repo_path = self._mkdtemp(suffix="svn_test_repo")
        svn_repo_url = "file://%s" % svn_repo_path  # Not sure this will work on windows
        # git svn complains if we don't pass --pre-1.5-compatible, not sure why:
        # Expected FS format '2'; found format '3' at /usr/local/libexec/git-core//git-svn line 1477
        self._run(
            ['svnadmin', 'create', '--pre-1.5-compatible', svn_repo_path])

        # Create a test svn checkout
        svn_checkout_path = self._mkdtemp(suffix="svn_test_checkout")
        self._run(
            ['svn', 'checkout', '--quiet', svn_repo_url, svn_checkout_path])

        # Create and checkout a trunk dir to match the standard svn configuration to match git-svn's expectations
        self._chdir(svn_checkout_path)
        self._mkdir('trunk')
        self._svn_add('trunk')
        # We can add tags and branches as well if we ever need to test those.
        self._svn_commit('add trunk')

        self._rmtree(svn_checkout_path)

        self._set_up_svn_test_commits(svn_repo_url + "/trunk")
        return svn_repo_path

    def _set_up_svn_test_commits(self, svn_repo_url):
        svn_checkout_path = self._mkdtemp(suffix="svn_test_checkout")
        self._run(
            ['svn', 'checkout', '--quiet', svn_repo_url, svn_checkout_path])

        # Add some test commits
        self._chdir(svn_checkout_path)

        self._write_text_file("test_file", "test1")
        self._svn_add("test_file")
        self._svn_commit("initial commit")

        self._write_text_file("test_file", "test1test2")
        # This used to be the last commit, but doing so broke
        # GitTest.test_apply_git_patch which use the inverse diff of the last commit.
        # svn-apply fails to remove directories in Git, see:
        # https://bugs.webkit.org/show_bug.cgi?id=34871
        self._mkdir("test_dir")
        # Slash should always be the right path separator since we use cygwin on Windows.
        test_file3_path = "test_dir/test_file3"
        self._write_text_file(test_file3_path, "third file")
        self._svn_add("test_dir")
        self._svn_commit("second commit")

        self._write_text_file("test_file", "test1test2test3\n")
        self._write_text_file("test_file2", "second file")
        self._svn_add("test_file2")
        self._svn_commit("third commit")

        # This 4th commit is used to make sure that our patch file handling
        # code correctly treats patches as binary and does not attempt to
        # decode them assuming they're utf-8.
        self._write_binary_file("test_file",
                                u"latin1 test: \u00A0\n".encode("latin-1"))
        self._write_binary_file("test_file2",
                                u"utf-8 test: \u00A0\n".encode("utf-8"))
        self._svn_commit("fourth commit")

        # svn does not seem to update after commit as I would expect.
        self._run(['svn', 'update'])
        self._rmtree(svn_checkout_path)

    def _tear_down_svn_checkout(self):
        self._rmtree(self.temp_directory)

    def _shared_test_add_recursively(self):
        self._mkdir("added_dir")
        self._write_text_file("added_dir/added_file", "new stuff")
        self.scm.add("added_dir/added_file")
        self.assertIn("added_dir/added_file", self.scm._added_files())

    def _shared_test_delete_recursively(self):
        self._mkdir("added_dir")
        self._write_text_file("added_dir/added_file", "new stuff")
        self.scm.add("added_dir/added_file")
        self.assertIn("added_dir/added_file", self.scm._added_files())
        self.scm.delete("added_dir/added_file")
        self.assertNotIn("added_dir", self.scm._added_files())

    def _shared_test_delete_recursively_or_not(self):
        self._mkdir("added_dir")
        self._write_text_file("added_dir/added_file", "new stuff")
        self._write_text_file("added_dir/another_added_file", "more new stuff")
        self.scm.add("added_dir/added_file")
        self.scm.add("added_dir/another_added_file")
        self.assertIn("added_dir/added_file", self.scm._added_files())
        self.assertIn("added_dir/another_added_file", self.scm._added_files())
        self.scm.delete("added_dir/added_file")
        self.assertIn("added_dir/another_added_file", self.scm._added_files())

    def _shared_test_exists(self, scm, commit_function):
        self._chdir(scm.checkout_root)
        self.assertFalse(scm.exists('foo.txt'))
        self._write_text_file('foo.txt', 'some stuff')
        self.assertFalse(scm.exists('foo.txt'))
        scm.add('foo.txt')
        commit_function('adding foo')
        self.assertTrue(scm.exists('foo.txt'))
        scm.delete('foo.txt')
        commit_function('deleting foo')
        self.assertFalse(scm.exists('foo.txt'))

    def _shared_test_move(self):
        self._write_text_file('added_file', 'new stuff')
        self.scm.add('added_file')
        self.scm.move('added_file', 'moved_file')
        self.assertIn('moved_file', self.scm._added_files())

    def _shared_test_move_recursive(self):
        self._mkdir("added_dir")
        self._write_text_file('added_dir/added_file', 'new stuff')
        self._write_text_file('added_dir/another_added_file', 'more new stuff')
        self.scm.add('added_dir')
        self.scm.move('added_dir', 'moved_dir')
        self.assertIn('moved_dir/added_file', self.scm._added_files())
        self.assertIn('moved_dir/another_added_file', self.scm._added_files())
Esempio n. 12
0
class SCMTestBase(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(SCMTestBase, self).__init__(*args, **kwargs)
        self.scm = None
        self.executive = None
        self.fs = None
        self.original_cwd = None

    def setUp(self):
        self.executive = Executive()
        self.fs = FileSystem()
        self.original_cwd = self.fs.getcwd()

    def tearDown(self):
        self._chdir(self.original_cwd)

    def _join(self, *comps):
        return self.fs.join(*comps)

    def _chdir(self, path):
        self.fs.chdir(path)

    def _mkdir(self, path):
        assert not self.fs.exists(path)
        self.fs.maybe_make_directory(path)

    def _mkdtemp(self, **kwargs):
        return str(self.fs.mkdtemp(**kwargs))

    def _remove(self, path):
        self.fs.remove(path)

    def _rmtree(self, path):
        self.fs.rmtree(path)

    def _run(self, *args, **kwargs):
        return self.executive.run_command(*args, **kwargs)

    def _run_silent(self, args, **kwargs):
        self.executive.run_command(args, **kwargs)

    def _write_text_file(self, path, contents):
        self.fs.write_text_file(path, contents)

    def _write_binary_file(self, path, contents):
        self.fs.write_binary_file(path, contents)

    def _make_diff(self, command, *args):
        # We use this wrapper to disable output decoding. diffs should be treated as
        # binary files since they may include text files of multiple different encodings.
        return self._run([command, "diff"] + list(args), decode_output=False)

    def _git_diff(self, *args):
        return self._make_diff("git", *args)

    def _shared_test_add_recursively(self):
        self._mkdir("added_dir")
        self._write_text_file("added_dir/added_file", "new stuff")
        self.scm.add("added_dir/added_file")
        self.assertIn("added_dir/added_file", self.scm._added_files())

    def _shared_test_delete_recursively(self):
        self._mkdir("added_dir")
        self._write_text_file("added_dir/added_file", "new stuff")
        self.scm.add("added_dir/added_file")
        self.assertIn("added_dir/added_file", self.scm._added_files())
        self.scm.delete("added_dir/added_file")
        self.assertNotIn("added_dir", self.scm._added_files())

    def _shared_test_delete_recursively_or_not(self):
        self._mkdir("added_dir")
        self._write_text_file("added_dir/added_file", "new stuff")
        self._write_text_file("added_dir/another_added_file", "more new stuff")
        self.scm.add("added_dir/added_file")
        self.scm.add("added_dir/another_added_file")
        self.assertIn("added_dir/added_file", self.scm._added_files())
        self.assertIn("added_dir/another_added_file", self.scm._added_files())
        self.scm.delete("added_dir/added_file")
        self.assertIn("added_dir/another_added_file", self.scm._added_files())

    def _shared_test_exists(self, scm, commit_function):
        self._chdir(scm.checkout_root)
        self.assertFalse(scm.exists('foo.txt'))
        self._write_text_file('foo.txt', 'some stuff')
        self.assertFalse(scm.exists('foo.txt'))
        scm.add('foo.txt')
        commit_function('adding foo')
        self.assertTrue(scm.exists('foo.txt'))
        scm.delete('foo.txt')
        commit_function('deleting foo')
        self.assertFalse(scm.exists('foo.txt'))

    def _shared_test_move(self):
        self._write_text_file('added_file', 'new stuff')
        self.scm.add('added_file')
        self.scm.move('added_file', 'moved_file')
        self.assertIn('moved_file', self.scm._added_files())

    def _shared_test_move_recursive(self):
        self._mkdir("added_dir")
        self._write_text_file('added_dir/added_file', 'new stuff')
        self._write_text_file('added_dir/another_added_file', 'more new stuff')
        self.scm.add('added_dir')
        self.scm.move('added_dir', 'moved_dir')
        self.assertIn('moved_dir/added_file', self.scm._added_files())
        self.assertIn('moved_dir/another_added_file', self.scm._added_files())
class CommitMessageForThisCommitTest(unittest.TestCase):
    def setUp(self):
        # FIXME: This should not need to touch the filesystem, however
        # ChangeLog is difficult to mock at current.
        self.filesystem = FileSystem()
        self.temp_dir = str(self.filesystem.mkdtemp(suffix="changelogs"))
        self.old_cwd = self.filesystem.getcwd()
        self.filesystem.chdir(self.temp_dir)
        self.webkit_base = WebKitFinder(self.filesystem).webkit_base()

        # Trick commit-log-editor into thinking we're in a Subversion working copy so it won't
        # complain about not being able to figure out what SCM is in use.
        # FIXME: VCSTools.pm is no longer so easily fooled.  It logs because "svn info" doesn't
        # treat a bare .svn directory being part of an svn checkout.
        self.filesystem.maybe_make_directory(".svn")

    def mock_changelog(self, changelogs):
        for path, contents in zip(self.changelog_paths, changelogs):
            self.filesystem.maybe_make_directory(self.filesystem.dirname(path))
            self.filesystem.write_text_file(path, contents)

    def tearDown(self):
        self.filesystem.rmtree(self.temp_dir)
        self.filesystem.chdir(self.old_cwd)

    def mock_checkout_for_test(self):
        executive = Executive()

        def mock_run(*args, **kwargs):
            # Note that we use a real Executive here, not a MockExecutive, so we can test that we're
            # invoking commit-log-editor correctly.
            env = os.environ.copy()
            env['CHANGE_LOG_EMAIL_ADDRESS'] = '*****@*****.**'
            kwargs['env'] = env
            return executive.run_command(*args, **kwargs)

        detector = SCMDetector(self.filesystem, executive)
        real_scm = detector.detect_scm_system(self.webkit_base)

        mock_scm = MockSCM()
        mock_scm.run = mock_run

        real_checkout = Checkout(real_scm)
        checkout = Checkout(mock_scm)
        checkout.script_path = real_checkout.script_path
        checkout.modified_changelogs = lambda git_commit, changed_files=None: self.changelog_paths

        return checkout

    def test_commit_message_for_unreviewed_changelogs_with_different_messages(self):
        expected_commit_message = u"""Unreviewed build fix to un-break webkit-patch land.

Tools:

Move commit_message_for_this_commit from scm to checkout
https://bugs.webkit.org/show_bug.cgi?id=36629

* Scripts/webkitpy/common/checkout/api.py: import scm.CommitMessage

LayoutTests:

Second part of this complicated change by me, Tor Arne Vestb\u00f8!

* Path/To/Complicated/File: Added.
"""

        self.changelog_paths = map(self.filesystem.abspath, (self.filesystem.join("Tools", "ChangeLog"), self.filesystem.join("LayoutTests", "ChangeLog")))

        self.mock_changelog((_changelog1, _changelog2))
        checkout = self.mock_checkout_for_test()
        commit_message = checkout.commit_message_for_this_commit(git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertMultiLineEqual(commit_message.message(), expected_commit_message)

    def test_commit_message_for_one_reviewed_changelog(self):
        expected_commit_message = u"""SECTORDER_FLAGS should be defined in target's xcconfig file, not Base.xcconfig
<http://webkit.org/b/135006>

Patch by David Kilzer <*****@*****.**> on 2014-07-17
Reviewed by Darin Adler.

* WebKit.xcodeproj/project.pbxproj: Remove references to unused
WebKit.xcconfig file.
"""

        self.changelog_paths = map(self.filesystem.abspath, [self.filesystem.join("Source/WebKit", "ChangeLog")])

        self.mock_changelog([_changelog3])
        checkout = self.mock_checkout_for_test()
        commit_message = checkout.commit_message_for_this_commit(git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertMultiLineEqual(commit_message.message(), expected_commit_message)

    def test_commit_message_for_changelogs_with_same_messages(self):
        expected_commit_message = u"""SECTORDER_FLAGS should be defined in target's xcconfig file, not Base.xcconfig
<http://webkit.org/b/135006>

Patch by David Kilzer <*****@*****.**> on 2014-07-17
Reviewed by Darin Adler.

Source/WebKit:

* WebKit.xcodeproj/project.pbxproj: Remove references to unused
WebKit.xcconfig file.

LayoutTests:

* Path/To/Complicated/File: Added.
"""

        self.changelog_paths = map(self.filesystem.abspath, (self.filesystem.join("Source/WebKit", "ChangeLog"), self.filesystem.join("LayoutTests", "ChangeLog")))

        self.mock_changelog((_changelog3, _changelog4))
        checkout = self.mock_checkout_for_test()
        commit_message = checkout.commit_message_for_this_commit(git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertMultiLineEqual(commit_message.message(), expected_commit_message)

    def test_commit_message_for_changelogs_with_different_messages(self):
        expected_commit_message = u"""SECTORDER_FLAGS should be defined in target's xcconfig file, not Base.xcconfig
<http://webkit.org/b/135006>

Patch by David Kilzer <*****@*****.**> on 2014-07-17
Reviewed by Darin Adler.

Source/WebKit:

* WebKit.xcodeproj/project.pbxproj: Remove references to unused
WebKit.xcconfig file.

LayoutTests:

Filler change.

* Path/To/Complicated/File: Added.
"""

        self.changelog_paths = map(self.filesystem.abspath, (self.filesystem.join("Source/WebKit", "ChangeLog"), self.filesystem.join("LayoutTests", "ChangeLog")))

        self.mock_changelog((_changelog3, _changelog5))
        checkout = self.mock_checkout_for_test()
        commit_message = checkout.commit_message_for_this_commit(git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertMultiLineEqual(commit_message.message(), expected_commit_message)

    def test_commit_message_for_one_rollout_changelog(self):
        expected_commit_message = u"""Rolling out r170340 and r170339.

Changeset r170339 broke the Apple Windows Debug and Release builds.

Reverted changesets:

"[Win] Build fix after r134209"
http://trac.webkit.org/changeset/170340

"[Win] Clean up and refactor WinLauncher"
https://bugs.webkit.org/show_bug.cgi?id=134209
http://trac.webkit.org/changeset/170339

Patch by Daniel Bates <*****@*****.**> on 2014-06-23
"""

        self.changelog_paths = map(self.filesystem.abspath, [self.filesystem.join("Tools", "ChangeLog")])

        self.mock_changelog([_changelog6])
        checkout = self.mock_checkout_for_test()
        commit_message = checkout.commit_message_for_this_commit(git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertMultiLineEqual(commit_message.message(), expected_commit_message)

    def test_commit_message_for_rollout_changelogs_with_different_directories(self):
        expected_commit_message = u"""Rolling out r170340 and r170339.

Changeset r170339 broke the Apple Windows Debug and Release builds.

Reverted changesets:

"[Win] Build fix after r134209"
http://trac.webkit.org/changeset/170340

"[Win] Clean up and refactor WinLauncher"
https://bugs.webkit.org/show_bug.cgi?id=134209
http://trac.webkit.org/changeset/170339

Patch by Daniel Bates <*****@*****.**> on 2014-06-23
"""

        self.changelog_paths = map(self.filesystem.abspath, (self.filesystem.join("Tools", "ChangeLog"), self.filesystem.join("Source/WebCore", "ChangeLog")))

        self.mock_changelog((_changelog6, _changelog6))
        checkout = self.mock_checkout_for_test()
        commit_message = checkout.commit_message_for_this_commit(git_commit=None, return_stderr=True)
        # Throw away the first line - a warning about unknown VCS root.
        commit_message.message_lines = commit_message.message_lines[1:]
        self.assertMultiLineEqual(commit_message.message(), expected_commit_message)
Esempio n. 14
0
class TextFileReaderTest(LoggingTestCase):

    class MockProcessor(ProcessorBase):

        """A processor for test purposes.

        This processor simply records the parameters passed to its process()
        method for later checking by the unittest test methods.
        """

        def __init__(self):
            self.processed = []
            """The parameters passed for all calls to the process() method."""

        def should_process(self, file_path):
            return not file_path.endswith('should_not_process.txt')

        def process(self, lines, file_path, test_kwarg=None):
            self.processed.append((lines, file_path, test_kwarg))

    def setUp(self):
        LoggingTestCase.setUp(self)
        # FIXME: This should be a MockFileSystem once TextFileReader is moved entirely on top of FileSystem.
        self.filesystem = FileSystem()
        self._temp_dir = str(self.filesystem.mkdtemp())
        self._processor = TextFileReaderTest.MockProcessor()
        self._file_reader = TextFileReader(self.filesystem, self._processor)

    def tearDown(self):
        LoggingTestCase.tearDown(self)
        self.filesystem.rmtree(self._temp_dir)

    def _create_file(self, rel_path, text):
        """Create a file with given text and return the path to the file."""
        # FIXME: There are better/more secure APIs for creating tmp file paths.
        file_path = self.filesystem.join(self._temp_dir, rel_path)
        self.filesystem.write_text_file(file_path, text)
        return file_path

    def _passed_to_processor(self):
        """Return the parameters passed to MockProcessor.process()."""
        return self._processor.processed

    def _assert_file_reader(self, passed_to_processor, file_count):
        """Assert the state of the file reader."""
        self.assertEqual(passed_to_processor, self._passed_to_processor())
        self.assertEqual(file_count, self._file_reader.file_count)

    def test_process_file__does_not_exist(self):
        try:
            self._file_reader.process_file('does_not_exist.txt')
        except SystemExit as err:
            self.assertEqual(str(err), '1')
        else:
            self.fail('No Exception raised.')
        self._assert_file_reader([], 1)
        self.assertLog(["ERROR: File does not exist: 'does_not_exist.txt'\n"])

    def test_process_file__is_dir(self):
        temp_dir = self.filesystem.join(self._temp_dir, 'test_dir')
        self.filesystem.maybe_make_directory(temp_dir)

        self._file_reader.process_file(temp_dir)

        # Because the log message below contains exception text, it is
        # possible that the text varies across platforms.  For this reason,
        # we check only the portion of the log message that we control,
        # namely the text at the beginning.
        log_messages = self.logMessages()
        # We remove the message we are looking at to prevent the tearDown()
        # from raising an exception when it asserts that no log messages
        # remain.
        message = log_messages.pop()

        self.assertTrue(message.startswith("WARNING: Could not read file. Skipping: '%s'\n  " % temp_dir))

        self._assert_file_reader([], 1)

    def test_process_file__should_not_process(self):
        file_path = self._create_file('should_not_process.txt', 'contents')

        self._file_reader.process_file(file_path)
        self._assert_file_reader([], 1)

    def test_process_file__multiple_lines(self):
        file_path = self._create_file('foo.txt', 'line one\r\nline two\n')

        self._file_reader.process_file(file_path)
        processed = [(['line one\r', 'line two', ''], file_path, None)]
        self._assert_file_reader(processed, 1)

    def test_process_file__file_stdin(self):
        file_path = self._create_file('-', 'file contents')

        self._file_reader.process_file(file_path=file_path, test_kwarg='foo')
        processed = [(['file contents'], file_path, 'foo')]
        self._assert_file_reader(processed, 1)

    def test_process_file__with_kwarg(self):
        file_path = self._create_file('foo.txt', 'file contents')

        self._file_reader.process_file(file_path=file_path, test_kwarg='foo')
        processed = [(['file contents'], file_path, 'foo')]
        self._assert_file_reader(processed, 1)

    def test_process_paths(self):
        # We test a list of paths that contains both a file and a directory.
        dir = self.filesystem.join(self._temp_dir, 'foo_dir')
        self.filesystem.maybe_make_directory(dir)

        file_path1 = self._create_file('file1.txt', 'foo')

        rel_path = self.filesystem.join('foo_dir', 'file2.txt')
        file_path2 = self._create_file(rel_path, 'bar')

        self._file_reader.process_paths([dir, file_path1])
        processed = [(['bar'], file_path2, None),
                     (['foo'], file_path1, None)]
        self._assert_file_reader(processed, 2)

    def test_count_delete_only_file(self):
        self._file_reader.count_delete_only_file()
        delete_only_file_count = self._file_reader.delete_only_file_count
        self.assertEqual(delete_only_file_count, 1)