Merge lp:~james-w/linaro-image-tools/make-package-content-optional into lp:linaro-image-tools/11.11
- make-package-content-optional
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 85 |
Proposed branch: | lp:~james-w/linaro-image-tools/make-package-content-optional |
Merge into: | lp:linaro-image-tools/11.11 |
Prerequisite: | lp:~james-w/linaro-image-tools/set-installed-packages |
Diff against target: |
605 lines (+192/-88) 5 files modified
hwpack/hardwarepack.py (+7/-4) hwpack/packages.py (+20/-10) hwpack/testing.py (+47/-7) hwpack/tests/test_hardwarepack.py (+32/-1) hwpack/tests/test_packages.py (+86/-66) |
To merge this branch: | bzr merge lp:~james-w/linaro-image-tools/make-package-content-optional |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Zygmunt Krynicki (community) | Approve | ||
Review via email: mp+35356@code.launchpad.net |
Commit message
Description of the change
Hi,
The specification calls for it to be optional whether debs are included
in the hardware pack or not.
To that end we need a way of specifying to the hwpack a list of packages
with name+version, but for which we don't want to include the content, and
shouldn't bother downloading it.
To that end here is a branch to make FetchedPackage.
it has everything else we need, and so making a new object would be overkill
IMO.
The next branch will actually look at the include-debs config option etc.,
this is just groundwork.
Thanks,
James
James Westby (james-w) wrote : | # |
On Tue, 14 Sep 2010 20:51:48 -0000, Zygmunt Krynicki <email address hidden> wrote:
> Review: Needs Fixing
> I don't see any bugs but some things are IMHO odd:
>
>
> Why is this needed, can't you just have content = None in __init__()
> and be done with it? What am I missing? In addition a content= setter
> would be better than a method that you might not call since content is
> a public attribute.
Agreed.
> I'm not sure I like this part. It seems like we need to reinvent the
> operators module to get it to play with assertThat. I would extend
> testtools to have assertThatNot instead (it's cleaner) or make it work
> well with regular python operators (if it's returning some sort of
> assertion object we can have __not__ and all the usual suspects)
This is taken from testtools, so it's the way they decided to go, I'm
just backporting it so that we don't require a too-new version of it.
Feel free to file a bug on testtools to discuss some of your ideas.
Thanks,
James
- 149. By James Westby
-
Remove set_content as it is not needed.
Zygmunt Krynicki (zyga) wrote : | # |
> > I'm not sure I like this part. It seems like we need to reinvent the
> > operators module to get it to play with assertThat. I would extend
> > testtools to have assertThatNot instead (it's cleaner) or make it work
> > well with regular python operators (if it's returning some sort of
> > assertion object we can have __not__ and all the usual suspects)
>
> This is taken from testtools, so it's the way they decided to go, I'm
> just backporting it so that we don't require a too-new version of it.
>
> Feel free to file a bug on testtools to discuss some of your ideas.
Understood, if you are just backporting a future API then it makes sense.
I would recommend though to keep the API in a separate file and mark it clearly as something that you copied from another project. This will make it possible to revisit and remove it in the future and keep things clear license-wise (although I believe both projects use the same license here)
Thanks
Zygmunt
James Westby (james-w) wrote : | # |
On Tue, 14 Sep 2010 20:51:48 -0000, Zygmunt Krynicki <email address hidden> wrote:
> Review: Needs Fixing
> I don't see any bugs but some things are IMHO odd:
>
>
> Why is this needed, can't you just have content = None in __init__()
> and be done with it?
Done, thanks.
James
Zygmunt Krynicki (zyga) wrote : | # |
Thanks, looks good now.
Approved
Preview Diff
1 | === modified file 'hwpack/hardwarepack.py' |
2 | --- hwpack/hardwarepack.py 2010-09-14 21:03:45 +0000 |
3 | +++ hwpack/hardwarepack.py 2010-09-14 21:03:45 +0000 |
4 | @@ -177,15 +177,18 @@ |
5 | tf.create_dir(self.PACKAGES_DIRNAME) |
6 | manifest_content = "" |
7 | for package in self.packages: |
8 | - tf.create_file_from_string( |
9 | - self.PACKAGES_DIRNAME + "/" + package.filename, |
10 | - package.content.read()) |
11 | + if package.content is not None: |
12 | + tf.create_file_from_string( |
13 | + self.PACKAGES_DIRNAME + "/" + package.filename, |
14 | + package.content.read()) |
15 | manifest_content += "%s=%s\n" % ( |
16 | package.name, package.version) |
17 | tf.create_file_from_string( |
18 | self.MANIFEST_FILENAME, manifest_content) |
19 | tf.create_file_from_string( |
20 | - self.PACKAGES_FILENAME, get_packages_file(self.packages)) |
21 | + self.PACKAGES_FILENAME, |
22 | + get_packages_file( |
23 | + [p for p in self.packages if p.content is not None])) |
24 | tf.create_dir(self.SOURCES_LIST_DIRNAME) |
25 | for source_name, source_info in self.sources.items(): |
26 | tf.create_file_from_string( |
27 | |
28 | === modified file 'hwpack/packages.py' |
29 | --- hwpack/packages.py 2010-09-14 21:03:45 +0000 |
30 | +++ hwpack/packages.py 2010-09-14 21:03:45 +0000 |
31 | @@ -114,8 +114,9 @@ |
32 | :type version: str |
33 | :ivar filename: the filename that the package has. |
34 | :type filename: str |
35 | - :ivar content: a file that the content of the package can be read from. |
36 | - :type content: a file-like object |
37 | + :ivar content: a file that the content of the package can be read from, |
38 | + or None if the content is not known. |
39 | + :type content: a file-like object or None |
40 | :ivar size: the size of the package |
41 | :type size: int |
42 | :ivar md5: the hex representation of the md5sum of the contents of |
43 | @@ -142,7 +143,7 @@ |
44 | :type recommends: str or None |
45 | """ |
46 | |
47 | - def __init__(self, name, version, filename, content, size, md5, |
48 | + def __init__(self, name, version, filename, size, md5, |
49 | architecture, depends=None, pre_depends=None, |
50 | conflicts=None, recommends=None): |
51 | """Create a FetchedPackage. |
52 | @@ -152,7 +153,6 @@ |
53 | self.name = name |
54 | self.version = version |
55 | self.filename = filename |
56 | - self.content = content |
57 | self.size = size |
58 | self.md5 = md5 |
59 | self.architecture = architecture |
60 | @@ -160,9 +160,10 @@ |
61 | self.pre_depends = pre_depends |
62 | self.conflicts = conflicts |
63 | self.recommends = recommends |
64 | + self.content = None |
65 | |
66 | @classmethod |
67 | - def from_apt(cls, pkg, filename, content): |
68 | + def from_apt(cls, pkg, filename, content=None): |
69 | """Create a FetchedPackage from a python-apt Version (package). |
70 | |
71 | This is an alternative constructor for FetchedPackages that |
72 | @@ -181,17 +182,24 @@ |
73 | pre_depends = stringify_relationship(pkg, "PreDepends") |
74 | conflicts = stringify_relationship(pkg, "Conflicts") |
75 | recommends = stringify_relationship(pkg, "Recommends") |
76 | - return cls( |
77 | - pkg.package.name, pkg.version, filename, content, pkg.size, |
78 | + pkg = cls( |
79 | + pkg.package.name, pkg.version, filename, pkg.size, |
80 | pkg.md5, pkg.architecture, depends=depends, |
81 | pre_depends=pre_depends, conflicts=conflicts, |
82 | recommends=recommends) |
83 | + if content is not None: |
84 | + pkg.content = content |
85 | + return pkg |
86 | |
87 | def __eq__(self, other): |
88 | + def get_content(pkg): |
89 | + return pkg.content and pkg.content.read() |
90 | + content = get_content(self) |
91 | + other_content = get_content(other) |
92 | return (self.name == other.name |
93 | and self.version == other.version |
94 | and self.filename == other.filename |
95 | - and self.content.read() == other.content.read() |
96 | + and content == other_content |
97 | and self.size == other.size |
98 | and self.md5 == other.md5 |
99 | and self.architecture == other.architecture |
100 | @@ -204,12 +212,14 @@ |
101 | return not self.__eq__(other) |
102 | |
103 | def __repr__(self): |
104 | + has_content = self.content and "yes" or "no" |
105 | return ( |
106 | '<%s name=%s version=%s size=%s md5=%s architecture=%s ' |
107 | - 'depends="%s" pre_depends="%s" conflicts="%s" recommends="%s">' |
108 | + 'depends="%s" pre_depends="%s" conflicts="%s" recommends="%s" ' |
109 | + 'has_content=%s>' |
110 | % (self.__class__.__name__, self.name, self.version, self.size, |
111 | self.md5, self.architecture, self.depends, self.pre_depends, |
112 | - self.conflicts, self.recommends)) |
113 | + self.conflicts, self.recommends, has_content)) |
114 | |
115 | |
116 | class IsolatedAptCache(object): |
117 | |
118 | === modified file 'hwpack/testing.py' |
119 | --- hwpack/testing.py 2010-09-14 21:03:45 +0000 |
120 | +++ hwpack/testing.py 2010-09-14 21:03:45 +0000 |
121 | @@ -56,7 +56,8 @@ |
122 | """ |
123 | |
124 | def __init__(self, name, version, architecture="all", depends=None, |
125 | - pre_depends=None, conflicts=None, recommends=None): |
126 | + pre_depends=None, conflicts=None, recommends=None, |
127 | + no_content=False): |
128 | self.name = name |
129 | self.version = version |
130 | self.architecture = architecture |
131 | @@ -64,23 +65,29 @@ |
132 | self.pre_depends = pre_depends |
133 | self.conflicts = conflicts |
134 | self.recommends = recommends |
135 | + self._no_content = no_content |
136 | |
137 | @property |
138 | def filename(self): |
139 | return "%s_%s_all.deb" % (self.name, self.version) |
140 | |
141 | + def _content_str(self): |
142 | + return "Content of %s" % self.filename |
143 | + |
144 | @property |
145 | def content(self): |
146 | - return StringIO("Content of %s" % self.filename) |
147 | + if self._no_content: |
148 | + return None |
149 | + return StringIO(self._content_str()) |
150 | |
151 | @property |
152 | def size(self): |
153 | - return len(self.content.read()) |
154 | + return len(self._content_str()) |
155 | |
156 | @property |
157 | def md5(self): |
158 | md5sum = hashlib.md5() |
159 | - md5sum.update(self.content.read()) |
160 | + md5sum.update(self._content_str()) |
161 | return md5sum.hexdigest() |
162 | |
163 | |
164 | @@ -217,6 +224,34 @@ |
165 | return None |
166 | |
167 | |
168 | +class Not: |
169 | + """Inverts a matcher.""" |
170 | + |
171 | + def __init__(self, matcher): |
172 | + self.matcher = matcher |
173 | + |
174 | + def __str__(self): |
175 | + return 'Not(%s)' % (self.matcher,) |
176 | + |
177 | + def match(self, other): |
178 | + mismatch = self.matcher.match(other) |
179 | + if mismatch is None: |
180 | + return MatchedUnexpectedly(self.matcher, other) |
181 | + else: |
182 | + return None |
183 | + |
184 | + |
185 | +class MatchedUnexpectedly: |
186 | + """A thing matched when it wasn't supposed to.""" |
187 | + |
188 | + def __init__(self, matcher, other): |
189 | + self.matcher = matcher |
190 | + self.other = other |
191 | + |
192 | + def describe(self): |
193 | + return "%r matches %s" % (self.other, self.matcher) |
194 | + |
195 | + |
196 | class HardwarePackHasFile(TarfileHasFile): |
197 | """A subclass of TarfileHasFile specific to hardware packs. |
198 | |
199 | @@ -265,10 +300,12 @@ |
200 | |
201 | class IsHardwarePack(Matcher): |
202 | |
203 | - def __init__(self, metadata, packages, sources): |
204 | + def __init__(self, metadata, packages, sources, |
205 | + packages_without_content=None): |
206 | self.metadata = metadata |
207 | self.packages = packages |
208 | self.sources = sources |
209 | + self.packages_without_content = packages_without_content or [] |
210 | |
211 | def match(self, path): |
212 | tf = tarfile.open(name=path, mode="r:gz") |
213 | @@ -282,12 +319,15 @@ |
214 | manifest += "%s=%s\n" % (package.name, package.version) |
215 | matchers.append(HardwarePackHasFile("manifest", content=manifest)) |
216 | matchers.append(HardwarePackHasFile("pkgs", type=tarfile.DIRTYPE)) |
217 | - for package in self.packages: |
218 | + packages_with_content = [p for p in self.packages |
219 | + if p not in self.packages_without_content] |
220 | + for package in packages_with_content: |
221 | matchers.append(HardwarePackHasFile( |
222 | "pkgs/%s" % package.filename, |
223 | content=package.content.read())) |
224 | matchers.append(HardwarePackHasFile( |
225 | - "pkgs/Packages", content=get_packages_file(self.packages))) |
226 | + "pkgs/Packages", |
227 | + content=get_packages_file(packages_with_content))) |
228 | matchers.append(HardwarePackHasFile( |
229 | "sources.list.d", type=tarfile.DIRTYPE)) |
230 | for source_id, sources_entry in self.sources.items(): |
231 | |
232 | === modified file 'hwpack/tests/test_hardwarepack.py' |
233 | --- hwpack/tests/test_hardwarepack.py 2010-09-14 17:17:43 +0000 |
234 | +++ hwpack/tests/test_hardwarepack.py 2010-09-14 21:03:45 +0000 |
235 | @@ -5,7 +5,7 @@ |
236 | |
237 | from hwpack.hardwarepack import HardwarePack, Metadata |
238 | from hwpack.packages import get_packages_file |
239 | -from hwpack.testing import DummyFetchedPackage, HardwarePackHasFile |
240 | +from hwpack.testing import DummyFetchedPackage, HardwarePackHasFile, Not |
241 | |
242 | |
243 | class MetadataTests(TestCase): |
244 | @@ -199,6 +199,15 @@ |
245 | HardwarePackHasFile("pkgs/%s" % package2.filename, |
246 | content=package2.content.read())) |
247 | |
248 | + def test_add_packages_without_content_leaves_out_debs(self): |
249 | + package1 = DummyFetchedPackage("foo", "1.1", no_content=True) |
250 | + hwpack = HardwarePack(self.metadata) |
251 | + hwpack.add_packages([package1]) |
252 | + tf = self.get_tarfile(hwpack) |
253 | + self.assertThat( |
254 | + tf, |
255 | + Not(HardwarePackHasFile("pkgs/%s" % package1.filename))) |
256 | + |
257 | def test_creates_Packages_file(self): |
258 | hwpack = HardwarePack(self.metadata) |
259 | tf = self.get_tarfile(hwpack) |
260 | @@ -221,6 +230,28 @@ |
261 | "pkgs/Packages", |
262 | content=get_packages_file([package1, package2]))) |
263 | |
264 | + def test_Packages_file_empty_with_no_deb_content(self): |
265 | + package1 = DummyFetchedPackage("foo", "1.1", no_content=True) |
266 | + package2 = DummyFetchedPackage("bar", "1.1", no_content=True) |
267 | + hwpack = HardwarePack(self.metadata) |
268 | + hwpack.add_packages([package1, package2]) |
269 | + tf = self.get_tarfile(hwpack) |
270 | + self.assertThat( |
271 | + tf, |
272 | + HardwarePackHasFile("pkgs/Packages", content="")) |
273 | + |
274 | + def test_Packages_file_correct_content_with_some_deb_content(self): |
275 | + package1 = DummyFetchedPackage("foo", "1.1", no_content=True) |
276 | + package2 = DummyFetchedPackage("bar", "1.1") |
277 | + hwpack = HardwarePack(self.metadata) |
278 | + hwpack.add_packages([package1, package2]) |
279 | + tf = self.get_tarfile(hwpack) |
280 | + self.assertThat( |
281 | + tf, |
282 | + HardwarePackHasFile( |
283 | + "pkgs/Packages", |
284 | + content=get_packages_file([package2]))) |
285 | + |
286 | def test_creates_sources_list_dir(self): |
287 | hwpack = HardwarePack(self.metadata) |
288 | tf = self.get_tarfile(hwpack) |
289 | |
290 | === modified file 'hwpack/tests/test_packages.py' |
291 | --- hwpack/tests/test_packages.py 2010-09-14 21:03:45 +0000 |
292 | +++ hwpack/tests/test_packages.py 2010-09-14 21:03:45 +0000 |
293 | @@ -147,179 +147,188 @@ |
294 | |
295 | def test_attributes(self): |
296 | package = FetchedPackage( |
297 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", |
298 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", |
299 | "armel") |
300 | self.assertEqual("foo", package.name) |
301 | self.assertEqual("1.1", package.version) |
302 | self.assertEqual("foo_1.1.deb", package.filename) |
303 | - self.assertEqual("xxxx", package.content.read()) |
304 | + self.assertEqual(None, package.content) |
305 | self.assertEqual(4, package.size) |
306 | self.assertEqual("aaaa", package.md5) |
307 | self.assertEqual("armel", package.architecture) |
308 | |
309 | def test_equal(self): |
310 | package1 = FetchedPackage( |
311 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
312 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
313 | package2 = FetchedPackage( |
314 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
315 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
316 | self.assertEqual(package1, package2) |
317 | self.assertFalse(package1 != package2) |
318 | |
319 | def test_not_equal_different_name(self): |
320 | package1 = FetchedPackage( |
321 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
322 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
323 | package2 = FetchedPackage( |
324 | - "bar", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
325 | + "bar", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
326 | self.assertNotEqual(package1, package2) |
327 | |
328 | def test_not_equal_different_version(self): |
329 | package1 = FetchedPackage( |
330 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
331 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
332 | package2 = FetchedPackage( |
333 | - "foo", "1.2", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
334 | + "foo", "1.2", "foo_1.1.deb", 4, "aaaa", "armel") |
335 | self.assertNotEqual(package1, package2) |
336 | |
337 | def test_not_equal_different_filename(self): |
338 | package1 = FetchedPackage( |
339 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
340 | - package2 = FetchedPackage( |
341 | - "foo", "1.1", "afoo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
342 | - self.assertNotEqual(package1, package2) |
343 | - |
344 | - def test_not_equal_different_content(self): |
345 | - package1 = FetchedPackage( |
346 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
347 | - package2 = FetchedPackage( |
348 | - "foo", "1.1", "foo_1.1.deb", StringIO("yyyy"), 4, "aaaa", "armel") |
349 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
350 | + package2 = FetchedPackage( |
351 | + "foo", "1.1", "afoo_1.1.deb", 4, "aaaa", "armel") |
352 | self.assertNotEqual(package1, package2) |
353 | |
354 | def test_not_equal_different_size(self): |
355 | package1 = FetchedPackage( |
356 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
357 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
358 | package2 = FetchedPackage( |
359 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 5, "aaaa", "armel") |
360 | + "foo", "1.1", "foo_1.1.deb", 5, "aaaa", "armel") |
361 | self.assertNotEqual(package1, package2) |
362 | |
363 | def test_not_equal_different_md5(self): |
364 | package1 = FetchedPackage( |
365 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
366 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
367 | package2 = FetchedPackage( |
368 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "bbbb", "armel") |
369 | + "foo", "1.1", "foo_1.1.deb", 4, "bbbb", "armel") |
370 | self.assertNotEqual(package1, package2) |
371 | |
372 | def test_not_equal_different_architecture(self): |
373 | package1 = FetchedPackage( |
374 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
375 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
376 | package2 = FetchedPackage( |
377 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "i386") |
378 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "i386") |
379 | self.assertNotEqual(package1, package2) |
380 | |
381 | def test_not_equal_different_depends(self): |
382 | package1 = FetchedPackage( |
383 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
384 | - depends="bar") |
385 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", depends="bar") |
386 | package2 = FetchedPackage( |
387 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
388 | - depends="baz") |
389 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", depends="baz") |
390 | self.assertNotEqual(package1, package2) |
391 | |
392 | def test_not_equal_different_depends_one_None(self): |
393 | package1 = FetchedPackage( |
394 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
395 | - depends="bar") |
396 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", depends="bar") |
397 | package2 = FetchedPackage( |
398 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
399 | - depends=None) |
400 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", depends=None) |
401 | self.assertNotEqual(package1, package2) |
402 | |
403 | def test_equal_same_depends(self): |
404 | package1 = FetchedPackage( |
405 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
406 | - depends="bar") |
407 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", depends="bar") |
408 | package2 = FetchedPackage( |
409 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
410 | - depends="bar") |
411 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", depends="bar") |
412 | self.assertEqual(package1, package2) |
413 | |
414 | def test_not_equal_different_pre_depends(self): |
415 | package1 = FetchedPackage( |
416 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
417 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
418 | pre_depends="bar") |
419 | package2 = FetchedPackage( |
420 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
421 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
422 | pre_depends="baz") |
423 | self.assertNotEqual(package1, package2) |
424 | |
425 | def test_not_equal_different_pre_depends_one_None(self): |
426 | package1 = FetchedPackage( |
427 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
428 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
429 | pre_depends="bar") |
430 | package2 = FetchedPackage( |
431 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
432 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
433 | pre_depends=None) |
434 | self.assertNotEqual(package1, package2) |
435 | |
436 | def test_equal_same_pre_depends(self): |
437 | package1 = FetchedPackage( |
438 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
439 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
440 | pre_depends="bar") |
441 | package2 = FetchedPackage( |
442 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
443 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
444 | pre_depends="bar") |
445 | self.assertEqual(package1, package2) |
446 | |
447 | def test_not_equal_different_conflicts(self): |
448 | package1 = FetchedPackage( |
449 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
450 | - conflicts="bar") |
451 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", conflicts="bar") |
452 | package2 = FetchedPackage( |
453 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
454 | - conflicts="baz") |
455 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", conflicts="baz") |
456 | self.assertNotEqual(package1, package2) |
457 | |
458 | def test_not_equal_different_conflicts_one_None(self): |
459 | package1 = FetchedPackage( |
460 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
461 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
462 | conflicts="bar") |
463 | package2 = FetchedPackage( |
464 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
465 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
466 | conflicts=None) |
467 | self.assertNotEqual(package1, package2) |
468 | |
469 | def test_equal_same_conflicts(self): |
470 | package1 = FetchedPackage( |
471 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
472 | - conflicts="bar") |
473 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", conflicts="bar") |
474 | package2 = FetchedPackage( |
475 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
476 | - conflicts="bar") |
477 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", conflicts="bar") |
478 | self.assertEqual(package1, package2) |
479 | |
480 | def test_not_equal_different_recommends(self): |
481 | package1 = FetchedPackage( |
482 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
483 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
484 | recommends="bar") |
485 | package2 = FetchedPackage( |
486 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
487 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
488 | recommends="baz") |
489 | self.assertNotEqual(package1, package2) |
490 | |
491 | def test_not_equal_different_recommends_one_None(self): |
492 | package1 = FetchedPackage( |
493 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
494 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
495 | recommends="bar") |
496 | package2 = FetchedPackage( |
497 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
498 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
499 | recommends=None) |
500 | self.assertNotEqual(package1, package2) |
501 | |
502 | def test_equal_same_recommends(self): |
503 | package1 = FetchedPackage( |
504 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
505 | - recommends="bar") |
506 | - package2 = FetchedPackage( |
507 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
508 | - recommends="bar") |
509 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
510 | + recommends="bar") |
511 | + package2 = FetchedPackage( |
512 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel", |
513 | + recommends="bar") |
514 | + self.assertEqual(package1, package2) |
515 | + |
516 | + def test_not_equal_different_contents(self): |
517 | + package1 = FetchedPackage( |
518 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
519 | + package1.content = StringIO("xxxx") |
520 | + package2 = FetchedPackage( |
521 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
522 | + package2.content = StringIO("yyyy") |
523 | + self.assertNotEqual(package1, package2) |
524 | + |
525 | + def test_not_equal_different_contents_one_unknown(self): |
526 | + package1 = FetchedPackage( |
527 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
528 | + package1.content = StringIO("xxxx") |
529 | + package2 = FetchedPackage( |
530 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
531 | + self.assertNotEqual(package1, package2) |
532 | + |
533 | + def test_equal_same_contents(self): |
534 | + package1 = FetchedPackage( |
535 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
536 | + package1.content = StringIO("xxxx") |
537 | + package2 = FetchedPackage( |
538 | + "foo", "1.1", "foo_1.1.deb", 4, "aaaa", "armel") |
539 | + package2.content = StringIO("xxxx") |
540 | self.assertEqual(package1, package2) |
541 | |
542 | def test_from_apt(self): |
543 | @@ -328,7 +337,8 @@ |
544 | with IsolatedAptCache([source.sources_entry]) as cache: |
545 | candidate = cache.cache['foo'].candidate |
546 | created_package = FetchedPackage.from_apt( |
547 | - candidate, target_package.filename, target_package.content) |
548 | + candidate, target_package.filename, |
549 | + content=target_package.content) |
550 | self.assertEqual(target_package, created_package) |
551 | |
552 | def assert_from_apt_translates_relationship(self, relationship): |
553 | @@ -339,7 +349,8 @@ |
554 | with IsolatedAptCache([source.sources_entry]) as cache: |
555 | candidate = cache.cache['foo'].candidate |
556 | created_package = FetchedPackage.from_apt( |
557 | - candidate, target_package.filename, target_package.content) |
558 | + candidate, target_package.filename, |
559 | + content=target_package.content) |
560 | self.assertEqual(target_package, created_package) |
561 | |
562 | def test_from_apt_with_depends(self): |
563 | @@ -354,6 +365,15 @@ |
564 | def test_from_apt_with_recommends(self): |
565 | self.assert_from_apt_translates_relationship('recommends') |
566 | |
567 | + def test_from_apt_without_content(self): |
568 | + target_package = DummyFetchedPackage("foo", "1.0") |
569 | + source = self.useFixture(AptSourceFixture([target_package])) |
570 | + with IsolatedAptCache([source.sources_entry]) as cache: |
571 | + candidate = cache.cache['foo'].candidate |
572 | + created_package = FetchedPackage.from_apt( |
573 | + candidate, target_package.filename) |
574 | + self.assertEqual(None, created_package.content) |
575 | + |
576 | |
577 | class AptCacheTests(TestCaseWithFixtures): |
578 | |
579 | @@ -554,7 +574,7 @@ |
580 | fetched = fetcher.fetch_packages(["bar"]) |
581 | self.assertEqual(new_source_packages[0], fetched[0]) |
582 | |
583 | - def test_fetch_package_records_correct_architecture(self): |
584 | + def test_fetch_packages_records_correct_architecture(self): |
585 | available_package = DummyFetchedPackage( |
586 | "foo", "1.0", architecture="nonexistant") |
587 | source = self.useFixture(AptSourceFixture([available_package])) |
588 | @@ -562,7 +582,7 @@ |
589 | self.assertEqual( |
590 | "nonexistant", fetcher.fetch_packages(["foo"])[0].architecture) |
591 | |
592 | - def test_fetch_package_fetches_from_correct_architecture(self): |
593 | + def test_fetch_packages_fetches_from_correct_architecture(self): |
594 | wanted_package = DummyFetchedPackage( |
595 | "foo", "1.0", architecture="arch1") |
596 | unwanted_package = DummyFetchedPackage( |
597 | @@ -573,7 +593,7 @@ |
598 | self.assertEqual( |
599 | wanted_package, fetcher.fetch_packages(["foo"])[0]) |
600 | |
601 | - def test_fetch_package_fetches_with_relationships(self): |
602 | + def test_fetch_packages_fetches_with_relationships(self): |
603 | depends = "foo" |
604 | pre_depends = "bar (>= 1.0)" |
605 | conflicts = "baz | zap" |
I don't see any bugs but some things are IMHO odd:
Why is this needed, can't you just have content = None in __init__() and be done with it? What am I missing? In addition a content= setter would be better than a method that you might not call since content is a public attribute.
64 + self.content = None
65 +
66 + def set_content(self, content):
67 + """Set the content of the package.
68 +
69 + :param content: the content of the package
70 + :type content: a file-like object
71 + """
72 + self.content = content
I'm not sure I like this part. It seems like we need to reinvent the operators module to get it to play with assertThat. I would extend testtools to have assertThatNot instead (it's cleaner) or make it work well with regular python operators (if it's returning some sort of assertion object we can have __not__ and all the usual suspects)
176 +class Not: match(other) edly(self. matcher, other)
177 + """Inverts a matcher."""
178 +
179 + def __init__(self, matcher):
180 + self.matcher = matcher
181 +
182 + def __str__(self):
183 + return 'Not(%s)' % (self.matcher,)
184 +
185 + def match(self, other):
186 + mismatch = self.matcher.
187 + if mismatch is None:
188 + return MatchedUnexpect
189 + else:
190 + return None