damned-lies r1233 - in trunk: . stats stats/management/commands stats/tests
- From: claudep svn gnome org
- To: svn-commits-list gnome org
- Subject: damned-lies r1233 - in trunk: . stats stats/management/commands stats/tests
- Date: Sat, 20 Dec 2008 22:07:55 +0000 (UTC)
Author: claudep
Date: Sat Dec 20 22:07:55 2008
New Revision: 1233
URL: http://svn.gnome.org/viewvc/damned-lies?rev=1233&view=rev
Log:
2008-12-20 Claude Paroz <claude 2xlibre net>
* stats/management/commands/update-stats.py: Enclose update_stats in a try
statement so as failure doesn't stop further updates.
* stats/models.py: Use exceptions for handling errors in checkout().
Use thread locking to prevent concurrent VCS checkout (in a same branch
instance).
Fix save() signature.
Subclass delete() function for branches to remove a VCS repo on the
filesystem when the branch is deleted.
* stats/tests/__init__.py: Add basic unit tests.
Added:
trunk/stats/tests/
trunk/stats/tests/__init__.py
Modified:
trunk/ChangeLog
trunk/stats/management/commands/update-stats.py
trunk/stats/models.py
Modified: trunk/stats/management/commands/update-stats.py
==============================================================================
--- trunk/stats/management/commands/update-stats.py (original)
+++ trunk/stats/management/commands/update-stats.py Sat Dec 20 22:07:55 2008
@@ -42,7 +42,10 @@
print "Updating stats for %s..." % (module_arg)
branches = Branch.objects.filter(module__name=module_arg)
for branch in branches.all():
- branch.update_stats(options['force'])
+ try:
+ branch.update_stats(options['force'])
+ except:
+ print "Error while updating stats for %s (branch '%s')" % (module_arg, branch.name)
else:
# Update all modules
modules = Module.objects.all()
@@ -50,7 +53,10 @@
print "Updating stats for %s..." % (mod.name)
branches = Branch.objects.filter(module__name=mod)
for branch in branches.all():
- branch.update_stats(options['force'])
+ try:
+ branch.update_stats(options['force'])
+ except:
+ print "Error while updating stats for %s (branch '%s')" % (module_arg, branch.name)
else:
return "Too much command line arguments."
Modified: trunk/stats/models.py
==============================================================================
--- trunk/stats/models.py (original)
+++ trunk/stats/models.py Sat Dec 20 22:07:55 2008
@@ -116,7 +116,9 @@
class BranchCharField(models.CharField):
def pre_save(self, model_instance, add):
""" Check if branch is valid before saving the instance """
- if not model_instance.checkout():
+ try:
+ model_instance.checkout()
+ except:
raise ValueError("Branch not valid: error while checking out the branch.")
return getattr(model_instance, self.attname)
@@ -134,14 +136,26 @@
ordering = ('name',)
unique_together = ('name', 'module')
+ def __init__(self, *args, **kwargs):
+ models.Model.__init__(self, *args, **kwargs)
+ self.checkout_lock = threading.Lock()
+
def __unicode__(self):
return "%s (%s)" % (self.name, self.module)
- def save(self):
- super(Branch, self).save()
+ def save(self, force_insert=False, force_update=False):
+ super(Branch, self).save(force_insert, force_update)
# The update command is launched asynchronously in a separate thread
upd_thread = threading.Thread(target=self.update_stats, kwargs={'force':True})
upd_thread.start()
+
+ def delete(self):
+ # Remove the repo checkout
+ localdir = os.path.join(settings.SCRATCHDIR, self.module.vcs_type, self.module.name + "." + self.name)
+ if os.access(localdir, os.W_OK):
+ import shutil # os.rmdir cannot delete non-empty dirs
+ shutil.rmtree(localdir)
+ models.Model.delete(self)
def __cmp__(self, other):
if self.name in BRANCH_HEAD_NAMES:
@@ -444,24 +458,22 @@
})
# Run command(s)
- errorsOccured = 0
if settings.DEBUG:
print >>sys.stdout, "Checking '%s.%s' out to '%s'..." % (module_name, self.name, modulepath)
- for command in commandList:
- if settings.DEBUG:
- print >>sys.stdout, command
- (error, output) = commands.getstatusoutput(command)
- if settings.DEBUG:
- print >> sys.stderr, output
- if error:
- errorsOccured = 1
+ # Do not allow 2 checkouts to run in parallel on the same branch
+ self.checkout_lock.acquire()
+ try:
+ for command in commandList:
if settings.DEBUG:
- print >> sys.stderr, error
- if errorsOccured:
- print >> sys.stderr, "Problem checking out module %s.%s" % (module_name, self.name)
- return 0
- else:
- return 1
+ print >>sys.stdout, command
+ (error, output) = commands.getstatusoutput(command)
+ if settings.DEBUG:
+ print >> sys.stderr, output
+ if error:
+ raise OSError(error, output)
+ finally:
+ self.checkout_lock.release()
+ return 1
DOMAIN_TYPE_CHOICES = (
Added: trunk/stats/tests/__init__.py
==============================================================================
--- (empty file)
+++ trunk/stats/tests/__init__.py Sat Dec 20 22:07:55 2008
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2008 Claude Paroz <claude 2xlibre net>
+#
+# This file is part of Damned Lies.
+#
+# Damned Lies 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.
+#
+# Damned Lies 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 Damned Lies; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import unittest
+import threading
+from stats.models import Module, Domain, Branch, Statistics
+
+class ModuleTestCase(unittest.TestCase):
+ def setUp(self):
+ self.mod = Module(name="gnome-hello",
+ bugs_base="http://bugzilla.gnome.org",
+ bugs_product="test", # This product really exists
+ bugs_component="test",
+ vcs_type="svn",
+ vcs_root="http://svn.gnome.org/svn",
+ vcs_web="http://svn.gnome.org/viewvc/gnome-hello")
+ self.mod.save()
+ dom = Domain(module=self.mod, name='po', description='UI Translations', dtype='ui', directory='po')
+ dom.save()
+ dom = Domain(module=self.mod, name='help', description='User Guide', dtype='doc', directory='help')
+ dom.save()
+
+ def testModuleFunctions(self):
+ self.assertEquals(self.mod.get_description(), 'gnome-hello')
+
+ def testBranch(self):
+ # Create branch (include checkout)
+ branch = Branch(name="trunk",
+ module = self.mod)
+ branch.save()
+
+ self.assertEquals(branch.is_head(), True)
+ self.assertEquals(branch.get_vcs_url(), "http://svn.gnome.org/svn/gnome-hello/trunk")
+ self.assertEquals(branch.get_vcs_web_url(), "http://svn.gnome.org/viewvc/gnome-hello/trunk")
+
+ # save() launch update_stats in a separate thread, wait for the thread to end before pursuing the tests
+ for th in threading.enumerate():
+ if th != threading.currentThread():
+ print "Waiting for thread %s to finish" % th.getName()
+ th.join()
+
+ # Check stats
+ fr_po_stat = Statistics.objects.get(branch=branch, domain__name='po', language__locale='fr')
+ self.assertEquals(fr_po_stat.translated, 40)
+ fr_doc_stat = Statistics.objects.get(branch=branch, domain__name='help', language__locale='fr')
+ self.assertEquals(fr_doc_stat.translated, 36)
+
+ # Delete branch to remove the repo checkout
+ branch.delete()
+
+ # TODO: Try to create a non-existing branch...
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]