Merge lp:~jtv/launchpad/bug-520651 into lp:launchpad

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Muharem Hrnjadovic
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~jtv/launchpad/bug-520651
Merge into: lp:launchpad
Diff against target: 132 lines (+56/-21)
2 files modified
lib/canonical/buildd/generate_translation_templates.py (+7/-2)
lib/canonical/buildd/tests/test_generate_translation_templates.py (+49/-19)
To merge this branch: bzr merge lp:~jtv/launchpad/bug-520651
Reviewer Review Type Date Requested Status
Muharem Hrnjadovic (community) code Approve
Review via email: mp+20632@code.launchpad.net

Commit message

Let TranslationTemplatesBuild slaves retrieve branch contents.

Description of the change

= Bug 520651 =

This ticks off one to-do item on the project of using the build farm to generate translation templates based on source code from a bzr branch. The item is: to make the slave code retrieve the source code from the branch.

I used the equivalent of a "bzr export" for this, which is the lightest-weight operation I could find that did the job. All it retrieves is the contents of the branch, in its current revision.

The test is not entirely realistic: it uses the pull URL for the branch (which is implemented using a Launchpad custom protocol that maps to file://) instead of the http public URL that the real build slave will get. The custom protocol requires the Launchpad bzr plugins, and special access to the bzr server. The real slave will go through plain http. The http way is more manageable when it comes to firewall holes, but as far as I've been able to find out from various knowledgeable developers, impossible to integration-test. Our test setup doesn't include http access to branches.

No lint. For Q/A we'll need some intimate time with dogfood and instructions on its use; if it fails we'll get TranslationTemplatesBuildJobs failing with "not a branch" errors.

To test,
{{{
./bin/test -vv -t test_generate_translation_templates
}}}

You'll notice that the test no longer needs a MockGenerateTranslationTemplates class. It wouldn't have suited the newly added test case anyway. Applying the new FakeMethod helper is enough.

In case the extraction of a method to create and populate a branch seems overweight: I have a feeling it may be a candidate for future reuse in the same test, but isn't quite worth moving into the factory either.

Jeroen

To post a comment you must log in.
Revision history for this message
Muharem Hrnjadovic (al-maisan) wrote :

Looks good!

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/canonical/buildd/generate_translation_templates.py'
--- lib/canonical/buildd/generate_translation_templates.py 2010-02-25 13:43:22 +0000
+++ lib/canonical/buildd/generate_translation_templates.py 2010-03-04 09:44:21 +0000
@@ -7,8 +7,12 @@
7import os.path7import os.path
8import sys8import sys
99
10from bzrlib.branch import Branch
11from bzrlib.export import export
12
10from lp.translations.pottery.buildd import generate_pots13from lp.translations.pottery.buildd import generate_pots
1114
15
12class GenerateTranslationTemplates:16class GenerateTranslationTemplates:
13 """Script to generate translation templates from a branch."""17 """Script to generate translation templates from a branch."""
1418
@@ -39,8 +43,9 @@
39 The branch is checked out to the location specified by43 The branch is checked out to the location specified by
40 `self.branch_dir`.44 `self.branch_dir`.
41 """45 """
42 # XXX JeroenVermeulen 2010-02-11 bug=520651: Read the contents46 branch = Branch.open(branch_url)
43 # of the branch using bzrlib.47 rev_tree = branch.basis_tree()
48 export(rev_tree, self.branch_dir)
4449
45 def generate(self):50 def generate(self):
46 """Do It. Generate templates."""51 """Do It. Generate templates."""
4752
=== modified file 'lib/canonical/buildd/tests/test_generate_translation_templates.py'
--- lib/canonical/buildd/tests/test_generate_translation_templates.py 2010-01-22 06:07:27 +0000
+++ lib/canonical/buildd/tests/test_generate_translation_templates.py 2010-03-04 09:44:21 +0000
@@ -4,37 +4,31 @@
4import os4import os
5from unittest import TestLoader5from unittest import TestLoader
66
7from lp.testing import TestCase7from lp.testing.fakemethod import FakeMethod
88
9from canonical.buildd.generate_translation_templates import (9from canonical.buildd.generate_translation_templates import (
10 GenerateTranslationTemplates)10 GenerateTranslationTemplates)
1111
12from canonical.launchpad.ftests.script import run_script12from canonical.launchpad.ftests.script import run_script
13from canonical.testing.layers import ZopelessDatabaseLayer13from canonical.testing.layers import ZopelessDatabaseLayer
1414from lp.code.model.directbranchcommit import DirectBranchCommit
1515from lp.testing import TestCaseWithFactory
16class MockGenerateTranslationTemplates(GenerateTranslationTemplates):16
17 """A GenerateTranslationTemplates with mocked _checkout."""17
18 # Records, for testing purposes, whether this object checked out a18class TestGenerateTranslationTemplates(TestCaseWithFactory):
19 # branch.
20 checked_out_branch = False
21
22 def _checkout(self, branch_url):
23 assert not self.checked_out_branch, "Checking out branch again!"
24 self.checked_out_branch = True
25
26
27class TestGenerateTranslationTemplates(TestCase):
28 """Test slave-side generate-translation-templates script."""19 """Test slave-side generate-translation-templates script."""
20 layer = ZopelessDatabaseLayer
21
29 def test_getBranch_url(self):22 def test_getBranch_url(self):
30 # If passed a branch URL, the template generation script will23 # If passed a branch URL, the template generation script will
31 # check out that branch into a directory called "source-tree."24 # check out that branch into a directory called "source-tree."
32 branch_url = 'lp://~my/translation/branch'25 branch_url = 'lp://~my/translation/branch'
3326
34 generator = MockGenerateTranslationTemplates(branch_url)27 generator = GenerateTranslationTemplates(branch_url)
28 generator._checkout = FakeMethod()
35 generator._getBranch()29 generator._getBranch()
3630
37 self.assertTrue(generator.checked_out_branch)31 self.assertEqual(1, generator._checkout.call_count)
38 self.assertTrue(generator.branch_dir.endswith('source-tree'))32 self.assertTrue(generator.branch_dir.endswith('source-tree'))
3933
40 def test_getBranch_dir(self):34 def test_getBranch_dir(self):
@@ -42,12 +36,48 @@
42 # works directly in that directory.36 # works directly in that directory.
43 branch_dir = '/home/me/branch'37 branch_dir = '/home/me/branch'
4438
45 generator = MockGenerateTranslationTemplates(branch_dir)39 generator = GenerateTranslationTemplates(branch_dir)
40 generator._checkout = FakeMethod()
46 generator._getBranch()41 generator._getBranch()
4742
48 self.assertFalse(generator.checked_out_branch)43 self.assertEqual(0, generator._checkout.call_count)
49 self.assertEqual(branch_dir, generator.branch_dir)44 self.assertEqual(branch_dir, generator.branch_dir)
5045
46 def _createBranch(self, content_map=None):
47 """Create a working branch.
48
49 :param content_map: optional dict mapping file names to file contents.
50 Each of these files with their contents will be written to the
51 branch.
52
53 :return: a fresh lp.code.model.Branch backed by a real bzr branch.
54 """
55 db_branch, tree = self.create_branch_and_tree(hosted=True)
56 populist = DirectBranchCommit(db_branch)
57 last_revision = populist.bzrbranch.last_revision()
58 db_branch.last_scanned_id = populist.last_scanned_id = last_revision
59
60 if content_map is not None:
61 for name, contents in content_map.iteritems():
62 populist.writeFile(name, contents)
63 populist.commit("Populating branch.")
64
65 return db_branch
66
67 def test_getBranch_bzr(self):
68 # _getBranch can retrieve branch contents from a branch URL.
69 self.useBzrBranches()
70 marker_text = "Ceci n'est pas cet branch."
71 branch = self._createBranch({'marker.txt': marker_text})
72 branch_url = branch.getPullURL()
73
74 generator = GenerateTranslationTemplates(branch_url)
75 generator.branch_dir = self.makeTemporaryDirectory()
76 generator._getBranch()
77
78 marker_file = file(os.path.join(generator.branch_dir, 'marker.txt'))
79 self.assertEqual(marker_text, marker_file.read())
80
51 def test_script(self):81 def test_script(self):
52 tempdir = self.makeTemporaryDirectory()82 tempdir = self.makeTemporaryDirectory()
53 (retval, out, err) = run_script(83 (retval, out, err) = run_script(