Rev 5810: Merge bzr.dev into config-hooks in file:///home/vila/src/bzr/experimental/config/

Vincent Ladeuil v.ladeuil+lp at free.fr
Fri Jun 17 09:12:47 UTC 2011


At file:///home/vila/src/bzr/experimental/config/

------------------------------------------------------------
revno: 5810 [merge]
revision-id: v.ladeuil+lp at free.fr-20110617091247-n2y9teccj86lm0oy
parent: v.ladeuil+lp at free.fr-20110616185810-xc6axtn65ze9329d
parent: pqm at pqm.ubuntu.com-20110616233147-l57xwon6dzb6waze
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: config-hooks
timestamp: Fri 2011-06-17 11:12:47 +0200
message:
  Merge bzr.dev into config-hooks
added:
  tools/subunit-sum              subunitsum-20110616103751-x5ovn49fga91b9zg-1
modified:
  bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
  bzrlib/osutils.py              osutils.py-20050309040759-eeaff12fbf77ac86
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/tests/features.py       features.py-20090820042958-jglgza3wrn03ha9e-1
  bzrlib/tests/test_osutils.py   test_osutils.py-20051201224856-e48ee24c12182989
  bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
  doc/en/release-notes/bzr-2.3.txt NEWS-20050323055033-4e00b5db738777ff
  doc/en/release-notes/bzr-2.4.txt bzr2.4.txt-20110114053217-k7ym9jfz243fddjm-1
  setup.py                       setup.py-20050314065409-02f8a0a6e3f9bc70
-------------- next part --------------
=== modified file 'bzrlib/__init__.py'
--- a/bzrlib/__init__.py	2011-05-27 21:41:02 +0000
+++ b/bzrlib/__init__.py	2011-06-16 21:28:07 +0000
@@ -52,7 +52,7 @@
 # Python version 2.0 is (2, 0, 0, 'final', 0)."  Additionally we use a
 # releaselevel of 'dev' for unreleased under-development code.
 
-version_info = (2, 4, 0, 'dev', 4)
+version_info = (2, 4, 0, 'dev', 5)
 
 # API compatibility version
 api_minimum_version = (2, 4, 0)

=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py	2011-05-27 03:40:07 +0000
+++ b/bzrlib/osutils.py	2011-06-16 18:34:26 +0000
@@ -2381,6 +2381,18 @@
     except UnicodeDecodeError:
         raise errors.BzrError("Can't decode username as %s." % \
                 user_encoding)
+    except ImportError, e:
+        if sys.platform != 'win32':
+            raise
+        if str(e) != 'No module named pwd':
+            raise
+        # https://bugs.launchpad.net/bzr/+bug/660174
+        # getpass.getuser() is unable to return username on Windows
+        # if there is no USERNAME environment variable set.
+        # That could be true if bzr is running as a service,
+        # e.g. running `bzr serve` as a service on Windows.
+        # We should not fail with traceback in this case.
+        username = u'UNKNOWN'
     return username
 
 

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2011-06-10 07:32:35 +0000
+++ b/bzrlib/tests/__init__.py	2011-06-16 19:00:24 +0000
@@ -989,6 +989,12 @@
         # is addressed -- vila 20110219
         self.overrideAttr(config, '_expand_default_value', None)
         self._log_files = set()
+        # Each key in the ``_counters`` dict holds a value for a different
+        # counter. When the test ends, addDetail() should be used to output the
+        # counter values. This happens in install_counter_hook().
+        self._counters = {}
+        if 'config_stats' in selftest_debug_flags:
+            self._install_config_stats_hooks()
 
     def debug(self):
         # debug a frame up.
@@ -1011,6 +1017,50 @@
         if name in details:
             del details[name]
 
+    def install_counter_hook(self, hooks, name, counter_name=None):
+        """Install a counting hook.
+
+        Any hook can be counted as long as it doesn't need to return a value.
+
+        :param hooks: Where the hook should be installed.
+
+        :param name: The hook name that will be counted.
+
+        :param counter_name: The counter identifier in ``_counters``, defaults
+            to ``name``.
+        """
+        _counters = self._counters # Avoid closing over self
+        if counter_name is None:
+            counter_name = name
+        if _counters.has_key(counter_name):
+            raise AssertionError('%s is already used as a counter name'
+                                  % (counter_name,))
+        _counters[counter_name] = 0
+        self.addDetail(counter_name, content.Content(content.UTF8_TEXT,
+            lambda: ['%d' % (_counters[counter_name],)]))
+        def increment_counter(*args, **kwargs):
+            _counters[counter_name] += 1
+        label = 'count %s calls' % (counter_name,)
+        hooks.install_named_hook(name, increment_counter, label)
+        self.addCleanup(hooks.uninstall_named_hook, name, label)
+
+    def _install_config_stats_hooks(self):
+        """Install config hooks to count hook calls.
+
+        """
+        for hook_name in ('get', 'set', 'remove', 'load', 'save'):
+            self.install_counter_hook(config.ConfigHooks, hook_name,
+                                       'config.%s' % (hook_name,))
+
+        # The OldConfigHooks are private and need special handling to protect
+        # against recursive tests (tests that run other tests), so we just do
+        # manually what registering them into _builtin_known_hooks will provide
+        # us.
+        self.overrideAttr(config, 'OldConfigHooks', config._OldConfigHooks())
+        for hook_name in ('get', 'set', 'remove', 'load', 'save'):
+            self.install_counter_hook(config.OldConfigHooks, hook_name,
+                                      'old_config.%s' % (hook_name,))
+
     def _clear_debug_flags(self):
         """Prevent externally set debug flags affecting tests.
 
@@ -3514,6 +3564,8 @@
 #                           with proper exclusion rules.
 #   -Ethreads               Will display thread ident at creation/join time to
 #                           help track thread leaks
+
+#   -Econfig_stats          Will collect statistics using addDetail
 selftest_debug_flags = set()
 
 

=== modified file 'bzrlib/tests/features.py'
--- a/bzrlib/tests/features.py	2011-03-14 12:43:19 +0000
+++ b/bzrlib/tests/features.py	2011-06-16 20:47:33 +0000
@@ -18,6 +18,7 @@
 
 import os
 import stat
+import sys
 
 from bzrlib import (
     osutils,
@@ -49,6 +50,7 @@
 pywintypes = tests.ModuleAvailableFeature('pywintypes')
 sphinx = tests.ModuleAvailableFeature('sphinx')
 subunit = tests.ModuleAvailableFeature('subunit')
+testtools = tests.ModuleAvailableFeature('testtools')
 
 
 class _BackslashDirSeparatorFeature(tests.Feature):
@@ -127,3 +129,17 @@
 bash_feature = ExecutableFeature('bash')
 sed_feature = ExecutableFeature('sed')
 diff_feature = ExecutableFeature('diff')
+
+
+class Win32Feature(tests.Feature):
+    """Feature testing whether we're running selftest on Windows
+    or Windows-like platform.
+    """
+
+    def _probe(self):
+        return sys.platform == 'win32'
+
+    def feature_name(self):
+        return "win32 platform"
+
+win32_feature = Win32Feature()

=== modified file 'bzrlib/tests/test_osutils.py'
--- a/bzrlib/tests/test_osutils.py	2011-05-13 12:51:05 +0000
+++ b/bzrlib/tests/test_osutils.py	2011-06-16 18:34:26 +0000
@@ -2052,6 +2052,7 @@
         # Whatever the result is, if we don't raise an exception, it's ok.
         osutils.terminal_width()
 
+
 class TestCreationOps(tests.TestCaseInTempDir):
     _test_needs_features = [features.chown_feature]
 
@@ -2087,6 +2088,7 @@
         self.assertEquals(self.uid, s.st_uid)
         self.assertEquals(self.gid, s.st_gid)
 
+
 class TestGetuserUnicode(tests.TestCase):
 
     def test_ascii_user(self):
@@ -2107,6 +2109,13 @@
         self.overrideEnv('LOGNAME', u'jrandom\xb6'.encode(ue))
         self.assertEqual(u'jrandom\xb6', osutils.getuser_unicode())
 
+    def test_no_username_bug_660174(self):
+        self.requireFeature(features.win32_feature)
+        for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
+            self.overrideEnv(name, None)
+        self.assertEqual(u'UNKNOWN', osutils.getuser_unicode())
+
+
 class TestBackupNames(tests.TestCase):
 
     def setUp(self):

=== modified file 'bzrlib/tests/test_selftest.py'
--- a/bzrlib/tests/test_selftest.py	2011-06-09 15:13:54 +0000
+++ b/bzrlib/tests/test_selftest.py	2011-06-16 21:23:44 +0000
@@ -43,6 +43,7 @@
     branchbuilder,
     bzrdir,
     errors,
+    hooks,
     lockdir,
     memorytree,
     osutils,
@@ -3559,3 +3560,44 @@
 
     def test_mutiple_excludes(self):
         self.assertTestList(['c'], '-x', 'a', '-x', 'b')
+
+
+class TestCounterHooks(tests.TestCase, SelfTestHelper):
+
+    _test_needs_features = [features.subunit]
+
+    def setUp(self):
+        super(TestCounterHooks, self).setUp()
+        class Test(tests.TestCase):
+
+            def setUp(self):
+                super(Test, self).setUp()
+                self.hooks = hooks.Hooks()
+                self.hooks.add_hook('myhook', 'Foo bar blah', (2,4))
+                self.install_counter_hook(self.hooks, 'myhook')
+
+            def no_hook(self):
+                pass
+
+            def run_hook_once(self):
+                for hook in self.hooks['myhook']:
+                    hook(self)
+
+        self.test_class = Test
+
+    def assertHookCalls(self, expected_calls, test_name):
+        test = self.test_class(test_name)
+        result = unittest.TestResult()
+        test.run(result)
+        self.assertTrue(hasattr(test, '_counters'))
+        self.assertTrue(test._counters.has_key('myhook'))
+        self.assertEquals(expected_calls, test._counters['myhook'])
+
+    def test_no_hook(self):
+        self.assertHookCalls(0, 'no_hook')
+
+    def test_run_hook_once(self):
+        tt = features.testtools
+        if tt.module.__version__ < (0, 9, 8):
+            raise tests.TestSkipped('testtools-0.9.8 required for addDetail')
+        self.assertHookCalls(1, 'run_hook_once')

=== modified file 'doc/en/release-notes/bzr-2.3.txt'
--- a/doc/en/release-notes/bzr-2.3.txt	2011-06-09 15:13:54 +0000
+++ b/doc/en/release-notes/bzr-2.3.txt	2011-06-16 18:34:26 +0000
@@ -33,6 +33,10 @@
 .. Fixes for situations where bzr would previously crash or give incorrect
    or undesirable results.
 
+* Don't fail with traceback if `bzr serve` is running as a service on Windows,
+  and there is no USERNAME, nor BZR_EMAIL or other whoami-related environment
+  variables set. (Alexander Belchenko, Bug #660174)
+
 Documentation
 *************
 

=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt	2011-06-16 17:39:40 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt	2011-06-16 21:28:07 +0000
@@ -5,10 +5,70 @@
 .. toctree::
    :maxdepth: 1
 
+bzr 2.4b5
+#########
+
+:2.4b5: NOT RELEASED YET
+
+External Compatibility Breaks
+*****************************
+
+.. These may require users to change the way they use Bazaar.
+
+New Features
+************
+
+.. New commands, options, etc that users may wish to try out.
+
+Improvements
+************
+
+.. Improvements to existing commands, especially improved performance 
+   or memory usage, or better results.
+
+Bug Fixes
+*********
+
+.. Fixes for situations where bzr would previously crash or give incorrect
+   or undesirable results.
+
+Documentation
+*************
+
+.. Improved or updated documentation.
+
+API Changes
+***********
+
+.. Changes that may require updates in plugins or other code that uses
+   bzrlib.
+
+Internals
+*********
+
+.. Major internal changes, unlikely to be visible to users or plugin 
+   developers, but interesting for bzr developers.
+
+Testing
+*******
+
+.. Fixes and changes that are only relevant to bzr's test framework and 
+   suite.  This can include new facilities for writing tests, fixes to 
+   spurious test failures and changes to the way things should be tested.
+
+
 bzr 2.4b4
 #########
 
-:2.4b4: NOT RELEASED YET
+:2.4b4: 2011-06-16
+
+This is the fourth beta of the 2.4 series, leading to a 2.4.0 release in
+August 2011. Beta releases are suitable for everyday use but may cause some
+incompatibilities with plugins.
+
+This release includes all bug fixed in previous series known at the time of
+this release.
+
 
 External Compatibility Breaks
 *****************************

=== modified file 'setup.py'
--- a/setup.py	2011-05-26 21:24:36 +0000
+++ b/setup.py	2011-06-16 18:34:26 +0000
@@ -478,6 +478,12 @@
     packages.append('sqlite3')
 
 
+def get_fastimport_py2exe_info(includes, excludes, packages):
+    # This is the python-fastimport package, not to be confused with the
+    # bzr-fastimport plugin.
+    packages.append('fastimport')
+
+
 if 'bdist_wininst' in sys.argv:
     def find_docs():
         docs = []
@@ -670,6 +676,9 @@
     if 'svn' in plugins:
         get_svn_py2exe_info(includes, excludes, packages)
 
+    if 'fastimport' in plugins:
+        get_fastimport_py2exe_info(includes, excludes, packages)
+
     if "TBZR" in os.environ:
         # TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
         # TortoiseOverlays MSI installer file. It is in the TSVN svn repo and

=== added file 'tools/subunit-sum'
--- a/tools/subunit-sum	1970-01-01 00:00:00 +0000
+++ b/tools/subunit-sum	2011-06-16 10:45:17 +0000
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+# Copyright (C) 2011 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Displays the sum of a counter found in a subunit stream.
+
+Each test have (or not) the counter as a named detail in the stream.
+"""
+
+import subunit
+import sys
+import testtools
+import unittest
+
+
+class TestSumCounter(testtools.TestResult):
+
+    def __init__(self, counter_names):
+        """Create a FilterResult object outputting to stream."""
+        testtools.TestResult.__init__(self)
+        self.counter_names = counter_names
+        self.totals = {}
+        self.longest = 0
+        for name in counter_names:
+            l = len(name)
+            if l > self.longest: self.longest = l
+            self.totals[name] = 0
+
+    def addSuccess(self, test, details):
+        for name in self.counter_names:
+            try:
+                counter_text = ''.join(details[name].iter_text())
+            except KeyError, e:
+                # this counter doesn't exist for the test
+                continue
+            self.totals[name] += int(counter_text)
+
+    def display_totals(self, stream):
+        for name in self.counter_names:
+            stream.write('%-*s: %s\n'
+                         % (self.longest, name, self.totals[name]))
+
+
+counter_names = sys.argv[1:]
+result = TestSumCounter(counter_names)
+test = subunit.ProtocolTestCase(sys.stdin)
+test.run(result)
+result.display_totals(sys.stdout)



More information about the bazaar-commits mailing list