Merge lp:~cjwatson/click/native-dpkg-architecture into lp:click

Proposed by Colin Watson
Status: Superseded
Proposed branch: lp:~cjwatson/click/native-dpkg-architecture
Merge into: lp:click
Diff against target: 280 lines (+212/-0)
7 files modified
click/chroot.py (+8/-0)
click/tests/test_chroot.py (+24/-0)
debian/changelog (+11/-0)
debian/control (+1/-0)
debian/tests/control (+3/-0)
debian/tests/run-tests.sh (+4/-0)
tests/integration/test_integration.py (+161/-0)
To merge this branch: bzr merge lp:~cjwatson/click/native-dpkg-architecture
Reviewer Review Type Date Requested Status
click hackers Pending
Review via email: mp+222690@code.launchpad.net

This proposal has been superseded by a proposal from 2014-06-10.

Commit message

Fix DEB_BUILD_* environment variables when building on amd64 for i386 (LP: #1328486).

Description of the change

When we're building on amd64 for i386 using "click chroot run", we override the native architecture to i386, but at the moment we don't fix up DEB_BUILD_* to match. That causes various problems such as cmake trying to use the wrong path to moc.

It doesn't appear to be possible to tell dpkg-architecture to use a different build architecture, short of supplying a mock "dpkg --print-architecture", which seems rather fragile. However, since we read its output and export it ourselves anyway, and we only need to worry about the case where the build and host architectures are being forced to be equal, we can just substitute DEB_HOST_* as DEB_BUILD_*.

To post a comment you must log in.
458. By Colin Watson

Mock "dpkg --print-architecture" so that we can select different native architectures in tests.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'click/chroot.py'
2--- click/chroot.py 2014-05-22 09:56:13 +0000
3+++ click/chroot.py 2014-06-10 17:04:03 +0000
4@@ -212,6 +212,14 @@
5 except ValueError:
6 continue
7 dpkg_architecture[key] = value
8+ if self.native_arch == self.target_arch:
9+ # We may have overridden the native architecture (see
10+ # _get_native_arch above), so we need to force DEB_BUILD_* to
11+ # match.
12+ for key in list(dpkg_architecture):
13+ if key.startswith("DEB_HOST_"):
14+ new_key = "DEB_BUILD_" + key[len("DEB_HOST_"):]
15+ dpkg_architecture[new_key] = dpkg_architecture[key]
16 return dpkg_architecture
17
18 def _generate_sources(self, series, native_arch, target_arch, components):
19
20=== modified file 'click/tests/test_chroot.py'
21--- click/tests/test_chroot.py 2014-05-20 11:52:16 +0000
22+++ click/tests/test_chroot.py 2014-06-10 17:04:03 +0000
23@@ -23,6 +23,8 @@
24 ]
25
26
27+import subprocess
28+
29 from click.tests.helpers import TestCase
30 from click.chroot import (
31 ClickChroot,
32@@ -42,6 +44,28 @@
33 chroot = ClickChroot("i386", "ubuntu-sdk-14.04", series="trusty")
34 self.assertEqual("i386", chroot._get_native_arch("amd64", "i386"))
35
36+ def test_dpkg_architecture_to_armhf(self):
37+ chroot = ClickChroot("armhf", "ubuntu-sdk-14.04", series="trusty")
38+ self.assertEqual("armhf", chroot.dpkg_architecture["DEB_HOST_ARCH"])
39+ system_arch = subprocess.check_output(
40+ ["dpkg", "--print-architecture"],
41+ universal_newlines=True).strip()
42+ self.assertEqual(
43+ system_arch, chroot.dpkg_architecture["DEB_BUILD_ARCH"])
44+
45+ def test_dpkg_architecture_to_i386(self):
46+ chroot = ClickChroot("i386", "ubuntu-sdk-14.04", series="trusty")
47+ self.assertEqual("i386", chroot.dpkg_architecture["DEB_HOST_ARCH"])
48+ system_arch = subprocess.check_output(
49+ ["dpkg", "--print-architecture"],
50+ universal_newlines=True).strip()
51+ if system_arch == "amd64":
52+ self.assertEqual(
53+ "i386", chroot.dpkg_architecture["DEB_BUILD_ARCH"])
54+ else:
55+ self.assertEqual(
56+ system_arch, chroot.dpkg_architecture["DEB_BUILD_ARCH"])
57+
58 def test_gen_sources_archive_only(self):
59 chroot = ClickChroot("amd64", "ubuntu-sdk-13.10", series="trusty")
60 chroot.native_arch = "i386"
61
62=== modified file 'debian/changelog'
63--- debian/changelog 2014-06-05 18:18:51 +0000
64+++ debian/changelog 2014-06-10 17:04:03 +0000
65@@ -1,3 +1,14 @@
66+click (0.4.26) UNRELEASED; urgency=medium
67+
68+ [ Michael Vogt ]
69+ * Add basic integration tests, run via autopkgtest.
70+
71+ [ Colin Watson ]
72+ * Fix DEB_BUILD_* environment variables when building on amd64 for i386
73+ (LP: #1328486).
74+
75+ -- Colin Watson <cjwatson@ubuntu.com> Mon, 09 Jun 2014 11:02:39 +0100
76+
77 click (0.4.25) utopic; urgency=medium
78
79 [ Ted Gould ]
80
81=== modified file 'debian/control'
82--- debian/control 2014-06-01 12:45:10 +0000
83+++ debian/control 2014-06-10 17:04:03 +0000
84@@ -9,6 +9,7 @@
85 X-Auto-Uploader: no-rewrite-version
86 X-Python-Version: >= 2.7
87 X-Python3-Version: >= 3.2
88+XS-Testsuite: autopkgtest
89
90 Package: click
91 Architecture: any
92
93=== added directory 'debian/tests'
94=== added file 'debian/tests/control'
95--- debian/tests/control 1970-01-01 00:00:00 +0000
96+++ debian/tests/control 2014-06-10 17:04:03 +0000
97@@ -0,0 +1,3 @@
98+Tests: run-tests.sh
99+Depends: @, iputils-ping, click-dev, schroot, debootstrap
100+Restrictions: needs-root allow-stderr
101\ No newline at end of file
102
103=== added file 'debian/tests/run-tests.sh'
104--- debian/tests/run-tests.sh 1970-01-01 00:00:00 +0000
105+++ debian/tests/run-tests.sh 2014-06-10 17:04:03 +0000
106@@ -0,0 +1,4 @@
107+#!/bin/sh
108+
109+python -m unittest discover tests.integration
110+#python3 -m unittest discover tests.integration
111
112=== added directory 'tests'
113=== added file 'tests/__init__.py'
114=== added directory 'tests/integration'
115=== added file 'tests/integration/__init__.py'
116=== added file 'tests/integration/test_integration.py'
117--- tests/integration/test_integration.py 1970-01-01 00:00:00 +0000
118+++ tests/integration/test_integration.py 2014-06-10 17:04:03 +0000
119@@ -0,0 +1,161 @@
120+# Copyright (C) 2014 Canonical Ltd.
121+# Author: Michael Vogt <michael.vogt@ubuntu.com>
122+
123+# This program is free software: you can redistribute it and/or modify
124+# it under the terms of the GNU General Public License as published by
125+# the Free Software Foundation; version 3 of the License.
126+#
127+# This program is distributed in the hope that it will be useful,
128+# but WITHOUT ANY WARRANTY; without even the implied warranty of
129+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
130+# GNU General Public License for more details.
131+#
132+# You should have received a copy of the GNU General Public License
133+# along with this program. If not, see <http://www.gnu.org/licenses/>.
134+
135+"""Integration tests for the click CLI interface."""
136+
137+import copy
138+import contextlib
139+import glob
140+import json
141+import os
142+import os.path
143+import random
144+import re
145+import shutil
146+import string
147+import subprocess
148+import sys
149+import tempfile
150+import unittest
151+
152+
153+@contextlib.contextmanager
154+def chdir(target):
155+ curdir = os.getcwd()
156+ os.chdir(target)
157+ yield
158+ os.chdir(curdir)
159+
160+
161+class TestCase(unittest.TestCase):
162+
163+ @classmethod
164+ def setUpClass(cls):
165+ cls.click_binary = os.path.abspath(
166+ os.path.join(sys.argv[0], "..", "bin", "click"))
167+
168+ def setUp(self):
169+ self.saved_env = copy.copy(os.environ)
170+ os.environ["PYTHONPATH"] = os.path.abspath(
171+ os.path.join(sys.argv[0], ".."))
172+
173+ def tearDown(self):
174+ os.environ = self.saved_env
175+
176+ def _make_click(self, name=None, version=1.0):
177+ if name is None:
178+ name = "com.ubuntu.%s" % "".join(random.choice(string.lowercase)
179+ for i in range(10))
180+ tmpdir = tempfile.mkdtemp()
181+ self.addCleanup(lambda: shutil.rmtree(tmpdir))
182+ clickdir = os.path.join(tmpdir, name)
183+ os.makedirs(clickdir)
184+ with open(os.path.join(clickdir, "manifest.json"), "w") as f:
185+ f.write("""{
186+ "name": "%s",
187+ "version": "%s",
188+ "maintainer": "Foo Bar <foo@example.org>",
189+ "title": "test title",
190+ "framework": "ubuntu-sdk-13.10"
191+ }""" % (name, version))
192+ with open(os.path.join(clickdir, "README"), "w") as f:
193+ f.write("hello world!")
194+ with chdir(tmpdir), open(os.devnull, "w") as devnull:
195+ subprocess.call(["click", "build", clickdir], stdout=devnull)
196+ generated_clicks = glob.glob(os.path.join(tmpdir, "*.click"))
197+ self.assertEqual(len(generated_clicks), 1)
198+ return generated_clicks[0]
199+
200+
201+class TestBuild(TestCase):
202+ def test_build(self):
203+ path_to_click = self._make_click()
204+ self.assertTrue(os.path.exists(path_to_click))
205+
206+
207+class TestInfo(TestCase):
208+ def test_info(self):
209+ name = "com.ubuntu.foo"
210+ path_to_click = self._make_click(name)
211+ output = subprocess.check_output([
212+ self.click_binary, "info", path_to_click])
213+ self.assertEqual(json.loads(output)["name"], name)
214+
215+
216+class TestVerify(TestCase):
217+ def test_verify_ok(self):
218+ name = "com.ubuntu.verify-ok"
219+ path_to_click = self._make_click(name)
220+ output = subprocess.check_output([
221+ self.click_binary, "verify", "--force-missing-framework",
222+ path_to_click])
223+ self.assertEqual(output, "")
224+
225+
226+class TestContents(TestCase):
227+ def test_contents(self):
228+ name = "com.ubuntu.contents"
229+ path_to_click = self._make_click(name)
230+ output = subprocess.check_output([
231+ self.click_binary, "contents", path_to_click])
232+ self.assertTrue(re.search(
233+ r'-rw-r[-w]-r-- root/root\s+[0-9]+\s+[0-9-]+ [0-9:]+ ./README', output))
234+
235+
236+@unittest.skipIf(
237+ os.getuid() != 0, "This tests needs to run as root")
238+@unittest.skipIf(
239+ subprocess.call(["ping", "-c1", "archive.ubuntu.com"]) != 0, "Need network")
240+class TestChroot(TestCase):
241+
242+ @classmethod
243+ def setUpClass(cls):
244+ super(TestChroot, cls).setUpClass()
245+ cls.arch = subprocess.check_output(
246+ ["dpkg", "--print-architecture"]).strip()
247+ subprocess.check_call([
248+ cls.click_binary,
249+ "chroot", "-a", cls.arch,
250+ "create"])
251+
252+ @classmethod
253+ def tearDownClass(cls):
254+ subprocess.check_call([
255+ cls.click_binary,
256+ "chroot", "-a", cls.arch,
257+ "destroy"])
258+
259+ def test_upgrade(self):
260+ subprocess.check_call([
261+ self.click_binary, "chroot", "-a", self.arch,
262+ "upgrade"])
263+
264+ def test_install(self):
265+ subprocess.check_call([
266+ self.click_binary, "chroot", "-a", self.arch,
267+ "install", "apt-utils"])
268+
269+ def test_run(self):
270+ output = subprocess.check_output([
271+ self.click_binary, "chroot", "-a", self.arch,
272+ "run", "echo", "hello world"])
273+ self.assertEqual(output, "hello world\n")
274+
275+ def test_maint(self):
276+ output = subprocess.check_output([
277+ self.click_binary, "chroot", "-a", self.arch,
278+ "maint", "id"])
279+ self.assertEqual(output, "uid=0(root) gid=0(root) groups=0(root)\n")
280+

Subscribers

People subscribed via source and target branches

to all changes: