Changeset 90480 in webkit


Ignore:
Timestamp:
Jul 6, 2011 12:10:25 PM (13 years ago)
Author:
dbates@webkit.org
Message:

2011-07-06 Daniel Bates <dbates@webkit.org>

Make SCM unit tests faster
https://bugs.webkit.org/show_bug.cgi?id=63883

Speeds up the SCM unit tests by a factor of 4. Currently, we create a
mock SVN repo for each test_ method in SVNTest and GitTest and creating
this repo is expensive.

Instead, it is significantly faster to create the mock SVN repo once
and then perform a filesystem copy of it for each test_ method.

Note, Python 2.7's unittest module implements support for per class and
per module setup and tear down methods which could be used to implement
similar functionality. At the time of writing, test-webkitpy is designed
to support Python 2.5. So, we can't take advantage of these Python 2.7
features :(

Reviewed by Eric Seidel.

  • Scripts/webkitpy/common/checkout/scm/scm_unittest.py:
Location:
trunk/Tools
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r90479 r90480  
     12011-07-06  Daniel Bates  <dbates@webkit.org>
     2
     3        Make SCM unit tests faster
     4        https://bugs.webkit.org/show_bug.cgi?id=63883
     5
     6        Speeds up the SCM unit tests by a factor of 4. Currently, we create a
     7        mock SVN repo for each test_ method in SVNTest and GitTest and creating
     8        this repo is expensive.
     9
     10        Instead, it is significantly faster to create the mock SVN repo once
     11        and then perform a filesystem copy of it for each test_ method.
     12
     13        Note, Python 2.7's unittest module implements support for per class and
     14        per module setup and tear down methods which could be used to implement
     15        similar functionality. At the time of writing, test-webkitpy is designed
     16        to support Python 2.5. So, we can't take advantage of these Python 2.7
     17        features :(
     18
     19        Reviewed by Eric Seidel.
     20
     21        * Scripts/webkitpy/common/checkout/scm/scm_unittest.py:
     22
    1232011-07-06  Adam Barth  <abarth@webkit.org>
    224
  • trunk/Tools/Scripts/webkitpy/common/checkout/scm/scm_unittest.py

    r90348 r90480  
    3131from __future__ import with_statement
    3232
     33import atexit
    3334import base64
    3435import codecs
     
    5859from .svn import SVN
    5960
     61# We cache the mock SVN repo so that we don't create it again for each call to an SVNTest or GitTest test_ method.
     62# We store it in a global variable so that we can delete this cached repo on exit(3).
     63# FIXME: Remove this once we migrate to Python 2.7. Unittest in Python 2.7 supports module-specific setup and teardown functions.
     64cached_svn_repo_path = None
     65
     66
     67def remove_dir(path):
     68    # Change directory to / to ensure that we aren't in the directory we want to delete.
     69    os.chdir('/')
     70    shutil.rmtree(path)
     71
     72
     73# FIXME: Remove this once we migrate to Python 2.7. Unittest in Python 2.7 supports module-specific setup and teardown functions.
     74@atexit.register
     75def delete_cached_mock_repo_at_exit():
     76    if cached_svn_repo_path:
     77        remove_dir(cached_svn_repo_path)
    6078
    6179# Eventually we will want to write tests which work for both scms. (like update_webkit, changed_files, etc.)
     
    112130
    113131    @classmethod
    114     def _setup_test_commits(cls, test_object):
     132    def _setup_test_commits(cls, svn_repo_url):
     133
     134        svn_checkout_path = tempfile.mkdtemp(suffix="svn_test_checkout")
     135        run_command(['svn', 'checkout', '--quiet', svn_repo_url, svn_checkout_path])
     136
    115137        # Add some test commits
    116         os.chdir(test_object.svn_checkout_path)
     138        os.chdir(svn_checkout_path)
    117139
    118140        write_into_file_at_path("test_file", "test1")
     
    146168        # svn does not seem to update after commit as I would expect.
    147169        run_command(['svn', 'update'])
    148 
     170        remove_dir(svn_checkout_path)
     171
     172    # This is a hot function since it's invoked by unittest before calling each test_ method in SVNTest and
     173    # GitTest. We create a mock SVN repo once and then perform an SVN checkout from a filesystem copy of
     174    # it since it's expensive to create the mock repo.
    149175    @classmethod
    150176    def setup(cls, test_object):
     177        global cached_svn_repo_path
     178        if not cached_svn_repo_path:
     179            cached_svn_repo_path = cls._setup_mock_repo()
     180
     181        test_object.temp_directory = tempfile.mkdtemp(suffix="svn_test")
     182        test_object.svn_repo_path = os.path.join(test_object.temp_directory, "repo")
     183        test_object.svn_repo_url = "file://%s" % test_object.svn_repo_path
     184        test_object.svn_checkout_path = os.path.join(test_object.temp_directory, "checkout")
     185        shutil.copytree(cached_svn_repo_path, test_object.svn_repo_path)
     186        run_command(['svn', 'checkout', '--quiet', test_object.svn_repo_url + "/trunk", test_object.svn_checkout_path])
     187
     188    @classmethod
     189    def _setup_mock_repo(cls):
    151190        # Create an test SVN repository
    152         test_object.svn_repo_path = tempfile.mkdtemp(suffix="svn_test_repo")
    153         test_object.svn_repo_url = "file://%s" % test_object.svn_repo_path # Not sure this will work on windows
     191        svn_repo_path = tempfile.mkdtemp(suffix="svn_test_repo")
     192        svn_repo_url = "file://%s" % svn_repo_path # Not sure this will work on windows
    154193        # git svn complains if we don't pass --pre-1.5-compatible, not sure why:
    155194        # Expected FS format '2'; found format '3' at /usr/local/libexec/git-core//git-svn line 1477
    156         run_command(['svnadmin', 'create', '--pre-1.5-compatible', test_object.svn_repo_path])
     195        run_command(['svnadmin', 'create', '--pre-1.5-compatible', svn_repo_path])
    157196
    158197        # Create a test svn checkout
    159         test_object.svn_checkout_path = tempfile.mkdtemp(suffix="svn_test_checkout")
    160         run_command(['svn', 'checkout', '--quiet', test_object.svn_repo_url, test_object.svn_checkout_path])
     198        svn_checkout_path = tempfile.mkdtemp(suffix="svn_test_checkout")
     199        run_command(['svn', 'checkout', '--quiet', svn_repo_url, svn_checkout_path])
    161200
    162201        # Create and checkout a trunk dir to match the standard svn configuration to match git-svn's expectations
    163         os.chdir(test_object.svn_checkout_path)
     202        os.chdir(svn_checkout_path)
    164203        os.mkdir('trunk')
    165204        cls._svn_add('trunk')
     
    168207
    169208        # Change directory out of the svn checkout so we can delete the checkout directory.
    170         # _setup_test_commits will CD back to the svn checkout directory.
    171         os.chdir('/')
    172         run_command(['rm', '-rf', test_object.svn_checkout_path])
    173         run_command(['svn', 'checkout', '--quiet', test_object.svn_repo_url + '/trunk', test_object.svn_checkout_path])
    174 
    175         cls._setup_test_commits(test_object)
     209        remove_dir(svn_checkout_path)
     210
     211        cls._setup_test_commits(svn_repo_url + "/trunk")
     212        return svn_repo_path
    176213
    177214    @classmethod
    178215    def tear_down(cls, test_object):
    179         run_command(['rm', '-rf', test_object.svn_repo_path])
    180         run_command(['rm', '-rf', test_object.svn_checkout_path])
     216        remove_dir(test_object.temp_directory)
    181217
    182218        # Now that we've deleted the checkout paths, cwddir may be invalid
Note: See TracChangeset for help on using the changeset viewer.