Merge lp:~jamesodhunt/ubuntu/wily/ubuntu-core-upgrader/call-upgrader-directly into lp:ubuntu/wily/ubuntu-core-upgrader

Proposed by James Hunt
Status: Work in progress
Proposed branch: lp:~jamesodhunt/ubuntu/wily/ubuntu-core-upgrader/call-upgrader-directly
Merge into: lp:ubuntu/wily/ubuntu-core-upgrader
Diff against target: 241 lines (+99/-15)
3 files modified
debian/changelog (+13/-0)
functional/test_upgrader.py (+85/-15)
ubuntucoreupgrader/upgrader.py (+1/-0)
To merge this branch: bzr merge lp:~jamesodhunt/ubuntu/wily/ubuntu-core-upgrader/call-upgrader-directly
Reviewer Review Type Date Requested Status
Ubuntu branches Pending
Review via email: mp+259481@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Michael Vogt (mvo) wrote :

I put some python code comments inline, I am not sure about the approach to test the python object and the executable in two different code paths. I think it would be preferable to convert the call_upgrader_object to use the in-tree binary to avoid having two code paths. Once the code calls a external executable (the bin/ubuntu-core-upgrader from this source tree) it will be trivial to convert to call a different one once the need arises (i.e. once there is a external one that needs testing).

So instead of call_upgrader_{object,command} maybe something like:
"""
def call_upgrader(command_file, root_dir):
    pyroot = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
    env = copy.copy(os.environ)
    env["PYTHONPATH"] = pyroot
    subprocess.check_call(
        [os.path.join(pyroot, "bin", "ubuntu-core-upgrade"),
         '--root-dir', root_dir,
         '--debug', '1',
         # don't delete the archive and command files.
         # The tests clean up after themselves so they will get removed then,
         # but useful to have them around to diagnose test failures.
         '--leave-files',
         command_file],
    env=env)
"""

Revision history for this message
James Hunt (jamesodhunt) wrote :

I'm slightly confused by this - if we replace call_upgrader_object() and call_upgrader_command() with a single call_upgrader(), most of the in-line comments are no longer relevant right?

Revision history for this message
Sebastien Bacher (seb128) wrote :

seems like work is needed/ongoing discussion is going with mvo, changing to "work in progress" to get out of the sponsoring queue

Unmerged revisions

33. By James Hunt

* functional/test_upgrader.py:
  - prepare(): Set cache dir to the root dir if '--root-dir' specified.
* ubuntucoreupgrader/upgrader.py:
  - If the real upgrader exists, use it rather than creating an Upgrader
    object. This will eventually allow the upgrader to be replaced (but
    these tests to be retained, atleast for the medium term).
  - Renamed call_upgrader() to call_upgrader_object().
  - Removed unused update argument for call_upgrader_object().

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2015-04-23 09:01:01 +0000
3+++ debian/changelog 2015-05-19 10:30:58 +0000
4@@ -1,3 +1,16 @@
5+ubuntu-core-upgrader (0.7.12) UNRELEASED; urgency=medium
6+
7+ * functional/test_upgrader.py:
8+ - prepare(): Set cache dir to the root dir if '--root-dir' specified.
9+ * ubuntucoreupgrader/upgrader.py:
10+ - If the real upgrader exists, use it rather than creating an Upgrader
11+ object. This will eventually allow the upgrader to be replaced (but
12+ these tests to be retained, atleast for the medium term).
13+ - Renamed call_upgrader() to call_upgrader_object().
14+ - Removed unused update argument for call_upgrader_object().
15+
16+ -- James Hunt <james.hunt@ubuntu.com> Tue, 19 May 2015 11:28:09 +0100
17+
18 ubuntu-core-upgrader (0.7.11) vivid; urgency=medium
19
20 * ubuntucoreupgrader/upgrader.py: Call os.sync() at end of sync_partitions()
21
22=== modified file 'functional/test_upgrader.py'
23--- functional/test_upgrader.py 2015-04-08 14:54:05 +0000
24+++ functional/test_upgrader.py 2015-05-19 10:30:58 +0000
25@@ -24,6 +24,7 @@
26 import sys
27 import os
28 import logging
29+import subprocess
30 import unittest
31
32 from ubuntucoreupgrader.upgrader import (
33@@ -42,16 +43,85 @@
34 UbuntuCoreUpgraderTestCase,
35 )
36
37+log = logging.getLogger()
38+
39 CMD_FILE = 'ubuntu_command'
40
41-
42-def call_upgrader(command_file, root_dir, update):
43+UPGRADER = '/usr/bin/ubuntu-core-upgrade'
44+
45+
46+def call_upgrader(command_file, root_dir, upgrader=UPGRADER):
47+
48+ found = False
49+
50+ if os.path.exists(upgrader):
51+ found = True
52+
53+ log.warning("Real upgrader ({}) {}found"
54+ .format(upgrader, "" if found else "not"))
55+
56+ if not found:
57+ log.warning("Creating an Upgrader object instead")
58+
59+ call_upgrader_object(command_file, root_dir)
60+ return
61+
62+ # Running on a system with the upgrader installed, so exercise it!
63+ log.warning("Calling upgrader directly")
64+
65+ options = [
66+ # always run with full debug
67+ '--debug', '2',
68+ # don't delete the archive and command files.
69+ # The tests clean up after themselves so they will get removed then,
70+ # but useful to have them around to diagnose test failures.
71+ '--leave-files',
72+ ]
73+
74+ if root_dir:
75+ options += ['--root-dir', root_dir]
76+
77+ call_upgrader_command(upgrader, options, command_file)
78+
79+
80+def call_upgrader_command(upgrader=UPGRADER, options=[],
81+ command_file=CMD_FILE):
82+ '''
83+ Invoke the upgrader binary directly.
84+
85+ :param upgrader: path to the upgrader to use.
86+ :param options: array of options to pass to the upgrader
87+ :param command_file: commands file to drive the upgrader.
88+ '''
89+ args = [upgrader]
90+ args.extend(options)
91+
92+ args += [command_file]
93+
94+ proc = subprocess.Popen(args,
95+ stdout=subprocess.PIPE,
96+ stderr=subprocess.PIPE,
97+ universal_newlines=True)
98+
99+ ret = proc.wait()
100+
101+ if ret == 0:
102+ return
103+
104+ stdout, stderr = proc.communicate()
105+ log.error("{} returned {}: stdout='{}', stderr='{}'"
106+ .format(args,
107+ ret,
108+ stdout,
109+ stderr))
110+
111+
112+def call_upgrader_object(command_file, root_dir):
113 '''
114 Invoke the upgrader.
115
116 :param command_file: commands file to drive the upgrader.
117 :param root_dir: Test directory to apply the upgrade to.
118- :param update: UpdateTree object.
119 '''
120
121 args = []
122@@ -207,7 +277,7 @@
123 # remove 'system' suffix that upgrader will add back on
124 vdir = os.path.split(self.victim_dir)[0]
125
126- call_upgrader(cmd_file, vdir, self.update)
127+ call_upgrader(cmd_file, vdir)
128
129 self.assertFalse(os.path.exists(file_path))
130
131@@ -232,7 +302,7 @@
132 self.assertTrue(os.path.isdir(dir_path))
133
134 vdir = os.path.split(self.victim_dir)[0]
135- call_upgrader(cmd_file, vdir, self.update)
136+ call_upgrader(cmd_file, vdir)
137
138 self.assertFalse(os.path.exists(dir_path))
139
140@@ -265,7 +335,7 @@
141 self.assertTrue(os.path.islink(link_file_path))
142
143 vdir = os.path.split(self.victim_dir)[0]
144- call_upgrader(cmd_file, vdir, self.update)
145+ call_upgrader(cmd_file, vdir)
146
147 # original file should still be there
148 self.assertTrue(os.path.exists(src_file_path))
149@@ -304,7 +374,7 @@
150 self.assertTrue(os.path.islink(link_file_path))
151
152 vdir = os.path.split(self.victim_dir)[0]
153- call_upgrader(cmd_file, vdir, self.update)
154+ call_upgrader(cmd_file, vdir)
155
156 # original directory should still be there
157 self.assertTrue(os.path.exists(src_dir_path))
158@@ -347,7 +417,7 @@
159 self.assertTrue(src_inode == link_inode)
160
161 vdir = os.path.split(self.victim_dir)[0]
162- call_upgrader(cmd_file, vdir, self.update)
163+ call_upgrader(cmd_file, vdir)
164
165 # original file should still be there
166 self.assertTrue(os.path.exists(src_file_path))
167@@ -388,7 +458,7 @@
168 self.assertTrue(os.path.isfile(file_path))
169
170 vdir = os.path.split(self.victim_dir)[0]
171- call_upgrader(cmd_file, vdir, self.update)
172+ call_upgrader(cmd_file, vdir)
173
174 # upgrader doesn't currently remove device files
175 self.assertTrue(os.path.exists(file_path))
176@@ -418,7 +488,7 @@
177 file_path = os.path.join(self.victim_dir, file)
178 self.assertFalse(os.path.exists(file_path))
179
180- call_upgrader(cmd_file, self.victim_dir, self.update)
181+ call_upgrader(cmd_file, self.victim_dir)
182
183 self.assertTrue(os.path.exists(file_path))
184 self.assertTrue(os.path.isfile(file_path))
185@@ -442,7 +512,7 @@
186 dir_path = os.path.join(self.victim_dir, dir)
187 self.assertFalse(os.path.exists(dir_path))
188
189- call_upgrader(cmd_file, self.victim_dir, self.update)
190+ call_upgrader(cmd_file, self.victim_dir)
191
192 self.assertTrue(os.path.exists(dir_path))
193 self.assertTrue(os.path.isdir(dir_path))
194@@ -487,7 +557,7 @@
195
196 self.assertFalse(os.path.exists(victim_link_file_path))
197
198- call_upgrader(cmd_file, self.victim_dir, self.update)
199+ call_upgrader(cmd_file, self.victim_dir)
200
201 self.assertTrue(os.path.exists(victim_src_file_path))
202 self.assertTrue(os.path.isfile(victim_src_file_path))
203@@ -538,7 +608,7 @@
204
205 self.assertFalse(os.path.exists(victim_link_file_path))
206
207- call_upgrader(cmd_file, self.victim_dir, self.update)
208+ call_upgrader(cmd_file, self.victim_dir)
209
210 self.assertTrue(os.path.exists(victim_src_file_path))
211 self.assertTrue(os.path.isfile(victim_src_file_path))
212@@ -581,7 +651,7 @@
213 self.assertFalse(os.path.exists(victim_src_file_path))
214 self.assertFalse(os.path.exists(victim_link_file_path))
215
216- call_upgrader(cmd_file, self.victim_dir, self.update)
217+ call_upgrader(cmd_file, self.victim_dir)
218
219 # source still shouldn't exist
220 self.assertFalse(os.path.exists(victim_src_file_path))
221@@ -622,7 +692,7 @@
222 # XXX: There is an implicit test here since if the upgrader
223 # fails (as documented on LP: #1437225), this test will also
224 # fail.
225- call_upgrader(cmd_file, vdir, self.update)
226+ call_upgrader(cmd_file, vdir)
227
228 self.assertTrue(os.path.exists(vdir))
229 self.assertTrue(os.path.exists(self.victim_dir))
230
231=== modified file 'ubuntucoreupgrader/upgrader.py'
232--- ubuntucoreupgrader/upgrader.py 2015-04-22 09:37:35 +0000
233+++ ubuntucoreupgrader/upgrader.py 2015-05-19 10:30:58 +0000
234@@ -553,6 +553,7 @@
235
236 if self.options.root_dir != '/':
237 # Don't modify root when running in test mode
238+ self.cache_dir = self.options.root_dir
239 return
240
241 def run(self):

Subscribers

People subscribed via source and target branches

to all changes: