gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / dulwich / tests / test_objects.py @ 959
History | View | Annotate | Download (44.9 KB)
1 |
# test_objects.py -- tests for objects.py
|
---|---|
2 |
# Copyright (C) 2007 James Westby <jw+debian@jameswestby.net>
|
3 |
#
|
4 |
# Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU
|
5 |
# General Public License as public by the Free Software Foundation; version 2.0
|
6 |
# or (at your option) any later version. You can redistribute it and/or
|
7 |
# modify it under the terms of either of these two licenses.
|
8 |
#
|
9 |
# Unless required by applicable law or agreed to in writing, software
|
10 |
# distributed under the License is distributed on an "AS IS" BASIS,
|
11 |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12 |
# See the License for the specific language governing permissions and
|
13 |
# limitations under the License.
|
14 |
#
|
15 |
# You should have received a copy of the licenses; if not, see
|
16 |
# <http://www.gnu.org/licenses/> for a copy of the GNU General Public License
|
17 |
# and <http://www.apache.org/licenses/LICENSE-2.0> for a copy of the Apache
|
18 |
# License, Version 2.0.
|
19 |
#
|
20 |
|
21 |
"""Tests for git base objects."""
|
22 |
|
23 |
# TODO: Round-trip parse-serialize-parse and serialize-parse-serialize tests.
|
24 |
|
25 |
|
26 |
from io import BytesIO |
27 |
import datetime |
28 |
from itertools import ( |
29 |
permutations, |
30 |
) |
31 |
import os |
32 |
import stat |
33 |
import warnings |
34 |
from contextlib import contextmanager |
35 |
|
36 |
from dulwich.errors import ( |
37 |
ObjectFormatException, |
38 |
) |
39 |
from dulwich.objects import ( |
40 |
Blob, |
41 |
Tree, |
42 |
Commit, |
43 |
ShaFile, |
44 |
Tag, |
45 |
TreeEntry, |
46 |
format_timezone, |
47 |
hex_to_sha, |
48 |
sha_to_hex, |
49 |
hex_to_filename, |
50 |
check_hexsha, |
51 |
check_identity, |
52 |
object_class, |
53 |
parse_timezone, |
54 |
pretty_format_tree_entry, |
55 |
parse_tree, |
56 |
_parse_tree_py, |
57 |
sorted_tree_items, |
58 |
_sorted_tree_items_py, |
59 |
) |
60 |
from dulwich.tests import ( |
61 |
TestCase, |
62 |
) |
63 |
from dulwich.tests.utils import ( |
64 |
make_commit, |
65 |
make_object, |
66 |
functest_builder, |
67 |
ext_functest_builder, |
68 |
) |
69 |
|
70 |
a_sha = b'6f670c0fb53f9463760b7295fbb814e965fb20c8'
|
71 |
b_sha = b'2969be3e8ee1c0222396a5611407e4769f14e54b'
|
72 |
c_sha = b'954a536f7819d40e6f637f849ee187dd10066349'
|
73 |
tree_sha = b'70c190eb48fa8bbb50ddc692a17b44cb781af7f6'
|
74 |
tag_sha = b'71033db03a03c6a36721efcf1968dd8f8e0cf023'
|
75 |
|
76 |
|
77 |
class TestHexToSha(TestCase): |
78 |
|
79 |
def test_simple(self): |
80 |
self.assertEqual(b'\xab\xcd' * 10, hex_to_sha(b'abcd' * 10)) |
81 |
|
82 |
def test_reverse(self): |
83 |
self.assertEqual(b'abcd' * 10, sha_to_hex(b'\xab\xcd' * 10)) |
84 |
|
85 |
|
86 |
class BlobReadTests(TestCase): |
87 |
"""Test decompression of blobs"""
|
88 |
|
89 |
def get_sha_file(self, cls, base, sha): |
90 |
dir = os.path.join(os.path.dirname(__file__), 'data', base)
|
91 |
return cls.from_path(hex_to_filename(dir, sha)) |
92 |
|
93 |
def get_blob(self, sha): |
94 |
"""Return the blob named sha from the test data dir"""
|
95 |
return self.get_sha_file(Blob, 'blobs', sha) |
96 |
|
97 |
def get_tree(self, sha): |
98 |
return self.get_sha_file(Tree, 'trees', sha) |
99 |
|
100 |
def get_tag(self, sha): |
101 |
return self.get_sha_file(Tag, 'tags', sha) |
102 |
|
103 |
def commit(self, sha): |
104 |
return self.get_sha_file(Commit, 'commits', sha) |
105 |
|
106 |
def test_decompress_simple_blob(self): |
107 |
b = self.get_blob(a_sha)
|
108 |
self.assertEqual(b.data, b'test 1\n') |
109 |
self.assertEqual(b.sha().hexdigest().encode('ascii'), a_sha) |
110 |
|
111 |
def test_hash(self): |
112 |
b = self.get_blob(a_sha)
|
113 |
self.assertEqual(hash(b.id), hash(b)) |
114 |
|
115 |
def test_parse_empty_blob_object(self): |
116 |
sha = b'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391'
|
117 |
b = self.get_blob(sha)
|
118 |
self.assertEqual(b.data, b'') |
119 |
self.assertEqual(b.id, sha)
|
120 |
self.assertEqual(b.sha().hexdigest().encode('ascii'), sha) |
121 |
|
122 |
def test_create_blob_from_string(self): |
123 |
string = b'test 2\n'
|
124 |
b = Blob.from_string(string) |
125 |
self.assertEqual(b.data, string)
|
126 |
self.assertEqual(b.sha().hexdigest().encode('ascii'), b_sha) |
127 |
|
128 |
def test_legacy_from_file(self): |
129 |
b1 = Blob.from_string(b'foo')
|
130 |
b_raw = b1.as_legacy_object() |
131 |
b2 = b1.from_file(BytesIO(b_raw)) |
132 |
self.assertEqual(b1, b2)
|
133 |
|
134 |
def test_chunks(self): |
135 |
string = b'test 5\n'
|
136 |
b = Blob.from_string(string) |
137 |
self.assertEqual([string], b.chunked)
|
138 |
|
139 |
def test_splitlines(self): |
140 |
for case in [ |
141 |
[], |
142 |
[b'foo\nbar\n'],
|
143 |
[b'bl\na', b'blie'], |
144 |
[b'bl\na', b'blie', b'bloe\n'], |
145 |
[b'', b'bl\na', b'blie', b'bloe\n'], |
146 |
[b'', b'', b'', b'bla\n'], |
147 |
[b'', b'', b'', b'bla\n', b''], |
148 |
[b'bl', b'', b'a\naaa'], |
149 |
[b'a\naaa', b'a'], |
150 |
]: |
151 |
b = Blob() |
152 |
b.chunked = case |
153 |
self.assertEqual(b.data.splitlines(True), b.splitlines()) |
154 |
|
155 |
def test_set_chunks(self): |
156 |
b = Blob() |
157 |
b.chunked = [b'te', b'st', b' 5\n'] |
158 |
self.assertEqual(b'test 5\n', b.data) |
159 |
b.chunked = [b'te', b'st', b' 6\n'] |
160 |
self.assertEqual(b'test 6\n', b.as_raw_string()) |
161 |
|
162 |
def test_parse_legacy_blob(self): |
163 |
string = b'test 3\n'
|
164 |
b = self.get_blob(c_sha)
|
165 |
self.assertEqual(b.data, string)
|
166 |
self.assertEqual(b.sha().hexdigest().encode('ascii'), c_sha) |
167 |
|
168 |
def test_eq(self): |
169 |
blob1 = self.get_blob(a_sha)
|
170 |
blob2 = self.get_blob(a_sha)
|
171 |
self.assertEqual(blob1, blob2)
|
172 |
|
173 |
def test_read_tree_from_file(self): |
174 |
t = self.get_tree(tree_sha)
|
175 |
self.assertEqual(t.items()[0], (b'a', 33188, a_sha)) |
176 |
self.assertEqual(t.items()[1], (b'b', 33188, b_sha)) |
177 |
|
178 |
def test_read_tree_from_file_parse_count(self): |
179 |
old_deserialize = Tree._deserialize |
180 |
def reset_deserialize(): |
181 |
Tree._deserialize = old_deserialize |
182 |
self.addCleanup(reset_deserialize)
|
183 |
self.deserialize_count = 0 |
184 |
def counting_deserialize(*args, **kwargs): |
185 |
self.deserialize_count += 1 |
186 |
return old_deserialize(*args, **kwargs)
|
187 |
Tree._deserialize = counting_deserialize |
188 |
t = self.get_tree(tree_sha)
|
189 |
self.assertEqual(t.items()[0], (b'a', 33188, a_sha)) |
190 |
self.assertEqual(t.items()[1], (b'b', 33188, b_sha)) |
191 |
self.assertEqual(self.deserialize_count, 1) |
192 |
|
193 |
def test_read_tag_from_file(self): |
194 |
t = self.get_tag(tag_sha)
|
195 |
self.assertEqual(t.object,
|
196 |
(Commit, b'51b668fd5bf7061b7d6fa525f88803e6cfadaa51'))
|
197 |
self.assertEqual(t.name, b'signed') |
198 |
self.assertEqual(t.tagger, b'Ali Sabil <ali.sabil@gmail.com>') |
199 |
self.assertEqual(t.tag_time, 1231203091) |
200 |
self.assertEqual(t.message, b'This is a signed tag\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.4.9 (GNU/Linux)\n\niEYEABECAAYFAkliqx8ACgkQqSMmLy9u/kcx5ACfakZ9NnPl02tOyYP6pkBoEkU1\n5EcAn0UFgokaSvS371Ym/4W9iJj6vh3h\n=ql7y\n-----END PGP SIGNATURE-----\n') |
201 |
|
202 |
def test_read_commit_from_file(self): |
203 |
sha = b'60dacdc733de308bb77bb76ce0fb0f9b44c9769e'
|
204 |
c = self.commit(sha)
|
205 |
self.assertEqual(c.tree, tree_sha)
|
206 |
self.assertEqual(c.parents,
|
207 |
[b'0d89f20333fbb1d2f3a94da77f4981373d8f4310'])
|
208 |
self.assertEqual(c.author,
|
209 |
b'James Westby <jw+debian@jameswestby.net>')
|
210 |
self.assertEqual(c.committer,
|
211 |
b'James Westby <jw+debian@jameswestby.net>')
|
212 |
self.assertEqual(c.commit_time, 1174759230) |
213 |
self.assertEqual(c.commit_timezone, 0) |
214 |
self.assertEqual(c.author_timezone, 0) |
215 |
self.assertEqual(c.message, b'Test commit\n') |
216 |
|
217 |
def test_read_commit_no_parents(self): |
218 |
sha = b'0d89f20333fbb1d2f3a94da77f4981373d8f4310'
|
219 |
c = self.commit(sha)
|
220 |
self.assertEqual(c.tree, b'90182552c4a85a45ec2a835cadc3451bebdfe870') |
221 |
self.assertEqual(c.parents, [])
|
222 |
self.assertEqual(c.author,
|
223 |
b'James Westby <jw+debian@jameswestby.net>')
|
224 |
self.assertEqual(c.committer,
|
225 |
b'James Westby <jw+debian@jameswestby.net>')
|
226 |
self.assertEqual(c.commit_time, 1174758034) |
227 |
self.assertEqual(c.commit_timezone, 0) |
228 |
self.assertEqual(c.author_timezone, 0) |
229 |
self.assertEqual(c.message, b'Test commit\n') |
230 |
|
231 |
def test_read_commit_two_parents(self): |
232 |
sha = b'5dac377bdded4c9aeb8dff595f0faeebcc8498cc'
|
233 |
c = self.commit(sha)
|
234 |
self.assertEqual(c.tree, b'd80c186a03f423a81b39df39dc87fd269736ca86') |
235 |
self.assertEqual(c.parents,
|
236 |
[b'ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd',
|
237 |
b'4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'])
|
238 |
self.assertEqual(c.author,
|
239 |
b'James Westby <jw+debian@jameswestby.net>')
|
240 |
self.assertEqual(c.committer,
|
241 |
b'James Westby <jw+debian@jameswestby.net>')
|
242 |
self.assertEqual(c.commit_time, 1174773719) |
243 |
self.assertEqual(c.commit_timezone, 0) |
244 |
self.assertEqual(c.author_timezone, 0) |
245 |
self.assertEqual(c.message, b'Merge ../b\n') |
246 |
|
247 |
def test_stub_sha(self): |
248 |
sha = b'5' * 40 |
249 |
c = make_commit(id=sha, message=b'foo')
|
250 |
self.assertTrue(isinstance(c, Commit)) |
251 |
self.assertEqual(sha, c.id)
|
252 |
self.assertNotEqual(sha, c.sha())
|
253 |
|
254 |
|
255 |
class ShaFileCheckTests(TestCase): |
256 |
|
257 |
def assertCheckFails(self, cls, data): |
258 |
obj = cls() |
259 |
def do_check(): |
260 |
obj.set_raw_string(data) |
261 |
obj.check() |
262 |
self.assertRaises(ObjectFormatException, do_check)
|
263 |
|
264 |
def assertCheckSucceeds(self, cls, data): |
265 |
obj = cls() |
266 |
obj.set_raw_string(data) |
267 |
self.assertEqual(None, obj.check()) |
268 |
|
269 |
|
270 |
small_buffer_zlib_object = ( |
271 |
b'\x48\x89\x15\xcc\x31\x0e\xc2\x30\x0c\x40\x51\xe6'
|
272 |
b'\x9c\xc2\x3b\xaa\x64\x37\xc4\xc1\x12\x42\x5c\xc5'
|
273 |
b'\x49\xac\x52\xd4\x92\xaa\x78\xe1\xf6\x94\xed\xeb'
|
274 |
b'\x0d\xdf\x75\x02\xa2\x7c\xea\xe5\x65\xd5\x81\x8b'
|
275 |
b'\x9a\x61\xba\xa0\xa9\x08\x36\xc9\x4c\x1a\xad\x88'
|
276 |
b'\x16\xba\x46\xc4\xa8\x99\x6a\x64\xe1\xe0\xdf\xcd'
|
277 |
b'\xa0\xf6\x75\x9d\x3d\xf8\xf1\xd0\x77\xdb\xfb\xdc'
|
278 |
b'\x86\xa3\x87\xf1\x2f\x93\xed\x00\xb7\xc7\xd2\xab'
|
279 |
b'\x2e\xcf\xfe\xf1\x3b\x50\xa4\x91\x53\x12\x24\x38'
|
280 |
b'\x23\x21\x86\xf0\x03\x2f\x91\x24\x52'
|
281 |
) |
282 |
|
283 |
|
284 |
class ShaFileTests(TestCase): |
285 |
|
286 |
def test_deflated_smaller_window_buffer(self): |
287 |
# zlib on some systems uses smaller buffers,
|
288 |
# resulting in a different header.
|
289 |
# See https://github.com/libgit2/libgit2/pull/464
|
290 |
sf = ShaFile.from_file(BytesIO(small_buffer_zlib_object)) |
291 |
self.assertEqual(sf.type_name, b'tag') |
292 |
self.assertEqual(sf.tagger, b' <@localhost>') |
293 |
|
294 |
|
295 |
class CommitSerializationTests(TestCase): |
296 |
|
297 |
def make_commit(self, **kwargs): |
298 |
attrs = {'tree': b'd80c186a03f423a81b39df39dc87fd269736ca86', |
299 |
'parents': [b'ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd', |
300 |
b'4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'],
|
301 |
'author': b'James Westby <jw+debian@jameswestby.net>', |
302 |
'committer': b'James Westby <jw+debian@jameswestby.net>', |
303 |
'commit_time': 1174773719, |
304 |
'author_time': 1174773719, |
305 |
'commit_timezone': 0, |
306 |
'author_timezone': 0, |
307 |
'message': b'Merge ../b\n'} |
308 |
attrs.update(kwargs) |
309 |
return make_commit(**attrs)
|
310 |
|
311 |
def test_encoding(self): |
312 |
c = self.make_commit(encoding=b'iso8859-1') |
313 |
self.assertTrue(b'encoding iso8859-1\n' in c.as_raw_string()) |
314 |
|
315 |
def test_short_timestamp(self): |
316 |
c = self.make_commit(commit_time=30) |
317 |
c1 = Commit() |
318 |
c1.set_raw_string(c.as_raw_string()) |
319 |
self.assertEqual(30, c1.commit_time) |
320 |
|
321 |
def test_full_tree(self): |
322 |
c = self.make_commit(commit_time=30) |
323 |
t = Tree() |
324 |
t.add(b'data-x', 0o644, Blob().id) |
325 |
c.tree = t |
326 |
c1 = Commit() |
327 |
c1.set_raw_string(c.as_raw_string()) |
328 |
self.assertEqual(t.id, c1.tree)
|
329 |
self.assertEqual(c.as_raw_string(), c1.as_raw_string())
|
330 |
|
331 |
def test_raw_length(self): |
332 |
c = self.make_commit()
|
333 |
self.assertEqual(len(c.as_raw_string()), c.raw_length()) |
334 |
|
335 |
def test_simple(self): |
336 |
c = self.make_commit()
|
337 |
self.assertEqual(c.id, b'5dac377bdded4c9aeb8dff595f0faeebcc8498cc') |
338 |
self.assertEqual(
|
339 |
b'tree d80c186a03f423a81b39df39dc87fd269736ca86\n'
|
340 |
b'parent ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd\n'
|
341 |
b'parent 4cffe90e0a41ad3f5190079d7c8f036bde29cbe6\n'
|
342 |
b'author James Westby <jw+debian@jameswestby.net> '
|
343 |
b'1174773719 +0000\n'
|
344 |
b'committer James Westby <jw+debian@jameswestby.net> '
|
345 |
b'1174773719 +0000\n'
|
346 |
b'\n'
|
347 |
b'Merge ../b\n', c.as_raw_string())
|
348 |
|
349 |
def test_timezone(self): |
350 |
c = self.make_commit(commit_timezone=(5 * 60)) |
351 |
self.assertTrue(b' +0005\n' in c.as_raw_string()) |
352 |
|
353 |
def test_neg_timezone(self): |
354 |
c = self.make_commit(commit_timezone=(-1 * 3600)) |
355 |
self.assertTrue(b' -0100\n' in c.as_raw_string()) |
356 |
|
357 |
def test_deserialize(self): |
358 |
c = self.make_commit()
|
359 |
d = Commit() |
360 |
d._deserialize(c.as_raw_chunks()) |
361 |
self.assertEqual(c, d)
|
362 |
|
363 |
def test_serialize_gpgsig(self): |
364 |
commit = self.make_commit(gpgsig=b"""-----BEGIN PGP SIGNATURE----- |
365 |
Version: GnuPG v1
|
366 |
|
367 |
iQIcBAABCgAGBQJULCdfAAoJEACAbyvXKaRXuKwP/RyP9PA49uAvu8tQVCC/uBa8
|
368 |
vi975+xvO14R8Pp8k2nps7lSxCdtCd+xVT1VRHs0wNhOZo2YCVoU1HATkPejqSeV
|
369 |
NScTHcxnk4/+bxyfk14xvJkNp7FlQ3npmBkA+lbV0Ubr33rvtIE5jiJPyz+SgWAg
|
370 |
xdBG2TojV0squj00GoH/euK6aX7GgZtwdtpTv44haCQdSuPGDcI4TORqR6YSqvy3
|
371 |
GPE+3ZqXPFFb+KILtimkxitdwB7CpwmNse2vE3rONSwTvi8nq3ZoQYNY73CQGkUy
|
372 |
qoFU0pDtw87U3niFin1ZccDgH0bB6624sLViqrjcbYJeg815Htsu4rmzVaZADEVC
|
373 |
XhIO4MThebusdk0AcNGjgpf3HRHk0DPMDDlIjm+Oao0cqovvF6VyYmcb0C+RmhJj
|
374 |
dodLXMNmbqErwTk3zEkW0yZvNIYXH7m9SokPCZa4eeIM7be62X6h1mbt0/IU6Th+
|
375 |
v18fS0iTMP/Viug5und+05C/v04kgDo0CPphAbXwWMnkE4B6Tl9sdyUYXtvQsL7x
|
376 |
0+WP1gL27ANqNZiI07Kz/BhbBAQI/+2TFT7oGr0AnFPQ5jHp+3GpUf6OKuT1wT3H
|
377 |
ND189UFuRuubxb42vZhpcXRbqJVWnbECTKVUPsGZqat3enQUB63uM4i6/RdONDZA
|
378 |
fDeF1m4qYs+cUXKNUZ03
|
379 |
=X6RT
|
380 |
-----END PGP SIGNATURE-----""")
|
381 |
self.maxDiff = None |
382 |
self.assertEqual(b"""\ |
383 |
tree d80c186a03f423a81b39df39dc87fd269736ca86
|
384 |
parent ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd
|
385 |
parent 4cffe90e0a41ad3f5190079d7c8f036bde29cbe6
|
386 |
author James Westby <jw+debian@jameswestby.net> 1174773719 +0000
|
387 |
committer James Westby <jw+debian@jameswestby.net> 1174773719 +0000
|
388 |
gpgsig -----BEGIN PGP SIGNATURE-----
|
389 |
Version: GnuPG v1
|
390 |
|
391 |
iQIcBAABCgAGBQJULCdfAAoJEACAbyvXKaRXuKwP/RyP9PA49uAvu8tQVCC/uBa8
|
392 |
vi975+xvO14R8Pp8k2nps7lSxCdtCd+xVT1VRHs0wNhOZo2YCVoU1HATkPejqSeV
|
393 |
NScTHcxnk4/+bxyfk14xvJkNp7FlQ3npmBkA+lbV0Ubr33rvtIE5jiJPyz+SgWAg
|
394 |
xdBG2TojV0squj00GoH/euK6aX7GgZtwdtpTv44haCQdSuPGDcI4TORqR6YSqvy3
|
395 |
GPE+3ZqXPFFb+KILtimkxitdwB7CpwmNse2vE3rONSwTvi8nq3ZoQYNY73CQGkUy
|
396 |
qoFU0pDtw87U3niFin1ZccDgH0bB6624sLViqrjcbYJeg815Htsu4rmzVaZADEVC
|
397 |
XhIO4MThebusdk0AcNGjgpf3HRHk0DPMDDlIjm+Oao0cqovvF6VyYmcb0C+RmhJj
|
398 |
dodLXMNmbqErwTk3zEkW0yZvNIYXH7m9SokPCZa4eeIM7be62X6h1mbt0/IU6Th+
|
399 |
v18fS0iTMP/Viug5und+05C/v04kgDo0CPphAbXwWMnkE4B6Tl9sdyUYXtvQsL7x
|
400 |
0+WP1gL27ANqNZiI07Kz/BhbBAQI/+2TFT7oGr0AnFPQ5jHp+3GpUf6OKuT1wT3H
|
401 |
ND189UFuRuubxb42vZhpcXRbqJVWnbECTKVUPsGZqat3enQUB63uM4i6/RdONDZA
|
402 |
fDeF1m4qYs+cUXKNUZ03
|
403 |
=X6RT
|
404 |
-----END PGP SIGNATURE-----
|
405 |
|
406 |
Merge ../b
|
407 |
""", commit.as_raw_string())
|
408 |
|
409 |
def test_serialize_mergetag(self): |
410 |
tag = make_object( |
411 |
Tag, object=(Commit, b'a38d6181ff27824c79fc7df825164a212eff6a3f'),
|
412 |
object_type_name=b'commit',
|
413 |
name=b'v2.6.22-rc7',
|
414 |
tag_time=1183319674,
|
415 |
tag_timezone=0,
|
416 |
tagger=b'Linus Torvalds <torvalds@woody.linux-foundation.org>',
|
417 |
message=default_message) |
418 |
commit = self.make_commit(mergetag=[tag])
|
419 |
|
420 |
self.assertEqual(b"""tree d80c186a03f423a81b39df39dc87fd269736ca86 |
421 |
parent ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd
|
422 |
parent 4cffe90e0a41ad3f5190079d7c8f036bde29cbe6
|
423 |
author James Westby <jw+debian@jameswestby.net> 1174773719 +0000
|
424 |
committer James Westby <jw+debian@jameswestby.net> 1174773719 +0000
|
425 |
mergetag object a38d6181ff27824c79fc7df825164a212eff6a3f
|
426 |
type commit
|
427 |
tag v2.6.22-rc7
|
428 |
tagger Linus Torvalds <torvalds@woody.linux-foundation.org> 1183319674 +0000
|
429 |
|
430 |
Linux 2.6.22-rc7
|
431 |
-----BEGIN PGP SIGNATURE-----
|
432 |
Version: GnuPG v1.4.7 (GNU/Linux)
|
433 |
|
434 |
iD8DBQBGiAaAF3YsRnbiHLsRAitMAKCiLboJkQECM/jpYsY3WPfvUgLXkACgg3ql
|
435 |
OK2XeQOiEeXtT76rV4t2WR4=
|
436 |
=ivrA
|
437 |
-----END PGP SIGNATURE-----
|
438 |
|
439 |
Merge ../b
|
440 |
""", commit.as_raw_string())
|
441 |
|
442 |
def test_serialize_mergetags(self): |
443 |
tag = make_object( |
444 |
Tag, object=(Commit, b'a38d6181ff27824c79fc7df825164a212eff6a3f'),
|
445 |
object_type_name=b'commit',
|
446 |
name=b'v2.6.22-rc7',
|
447 |
tag_time=1183319674,
|
448 |
tag_timezone=0,
|
449 |
tagger=b'Linus Torvalds <torvalds@woody.linux-foundation.org>',
|
450 |
message=default_message) |
451 |
commit = self.make_commit(mergetag=[tag, tag])
|
452 |
|
453 |
self.assertEqual(b"""tree d80c186a03f423a81b39df39dc87fd269736ca86 |
454 |
parent ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd
|
455 |
parent 4cffe90e0a41ad3f5190079d7c8f036bde29cbe6
|
456 |
author James Westby <jw+debian@jameswestby.net> 1174773719 +0000
|
457 |
committer James Westby <jw+debian@jameswestby.net> 1174773719 +0000
|
458 |
mergetag object a38d6181ff27824c79fc7df825164a212eff6a3f
|
459 |
type commit
|
460 |
tag v2.6.22-rc7
|
461 |
tagger Linus Torvalds <torvalds@woody.linux-foundation.org> 1183319674 +0000
|
462 |
|
463 |
Linux 2.6.22-rc7
|
464 |
-----BEGIN PGP SIGNATURE-----
|
465 |
Version: GnuPG v1.4.7 (GNU/Linux)
|
466 |
|
467 |
iD8DBQBGiAaAF3YsRnbiHLsRAitMAKCiLboJkQECM/jpYsY3WPfvUgLXkACgg3ql
|
468 |
OK2XeQOiEeXtT76rV4t2WR4=
|
469 |
=ivrA
|
470 |
-----END PGP SIGNATURE-----
|
471 |
mergetag object a38d6181ff27824c79fc7df825164a212eff6a3f
|
472 |
type commit
|
473 |
tag v2.6.22-rc7
|
474 |
tagger Linus Torvalds <torvalds@woody.linux-foundation.org> 1183319674 +0000
|
475 |
|
476 |
Linux 2.6.22-rc7
|
477 |
-----BEGIN PGP SIGNATURE-----
|
478 |
Version: GnuPG v1.4.7 (GNU/Linux)
|
479 |
|
480 |
iD8DBQBGiAaAF3YsRnbiHLsRAitMAKCiLboJkQECM/jpYsY3WPfvUgLXkACgg3ql
|
481 |
OK2XeQOiEeXtT76rV4t2WR4=
|
482 |
=ivrA
|
483 |
-----END PGP SIGNATURE-----
|
484 |
|
485 |
Merge ../b
|
486 |
""", commit.as_raw_string())
|
487 |
|
488 |
def test_deserialize_mergetag(self): |
489 |
tag = make_object( |
490 |
Tag, object=(Commit, b'a38d6181ff27824c79fc7df825164a212eff6a3f'),
|
491 |
object_type_name=b'commit',
|
492 |
name=b'v2.6.22-rc7',
|
493 |
tag_time=1183319674,
|
494 |
tag_timezone=0,
|
495 |
tagger=b'Linus Torvalds <torvalds@woody.linux-foundation.org>',
|
496 |
message=default_message) |
497 |
commit = self.make_commit(mergetag=[tag])
|
498 |
|
499 |
d = Commit() |
500 |
d._deserialize(commit.as_raw_chunks()) |
501 |
self.assertEqual(commit, d)
|
502 |
|
503 |
def test_deserialize_mergetags(self): |
504 |
tag = make_object( |
505 |
Tag, object=(Commit, b'a38d6181ff27824c79fc7df825164a212eff6a3f'),
|
506 |
object_type_name=b'commit',
|
507 |
name=b'v2.6.22-rc7',
|
508 |
tag_time=1183319674,
|
509 |
tag_timezone=0,
|
510 |
tagger=b'Linus Torvalds <torvalds@woody.linux-foundation.org>',
|
511 |
message=default_message) |
512 |
commit = self.make_commit(mergetag=[tag, tag])
|
513 |
|
514 |
d = Commit() |
515 |
d._deserialize(commit.as_raw_chunks()) |
516 |
self.assertEqual(commit, d)
|
517 |
|
518 |
|
519 |
default_committer = b'James Westby <jw+debian@jameswestby.net> 1174773719 +0000'
|
520 |
|
521 |
class CommitParseTests(ShaFileCheckTests): |
522 |
|
523 |
def make_commit_lines(self, |
524 |
tree=b'd80c186a03f423a81b39df39dc87fd269736ca86',
|
525 |
parents=[b'ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd',
|
526 |
b'4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'],
|
527 |
author=default_committer, |
528 |
committer=default_committer, |
529 |
encoding=None,
|
530 |
message=b'Merge ../b\n',
|
531 |
extra=None):
|
532 |
lines = [] |
533 |
if tree is not None: |
534 |
lines.append(b'tree ' + tree)
|
535 |
if parents is not None: |
536 |
lines.extend(b'parent ' + p for p in parents) |
537 |
if author is not None: |
538 |
lines.append(b'author ' + author)
|
539 |
if committer is not None: |
540 |
lines.append(b'committer ' + committer)
|
541 |
if encoding is not None: |
542 |
lines.append(b'encoding ' + encoding)
|
543 |
if extra is not None: |
544 |
for name, value in sorted(extra.items()): |
545 |
lines.append(name + b' ' + value)
|
546 |
lines.append(b'')
|
547 |
if message is not None: |
548 |
lines.append(message) |
549 |
return lines
|
550 |
|
551 |
def make_commit_text(self, **kwargs): |
552 |
return b'\n'.join(self.make_commit_lines(**kwargs)) |
553 |
|
554 |
def test_simple(self): |
555 |
c = Commit.from_string(self.make_commit_text())
|
556 |
self.assertEqual(b'Merge ../b\n', c.message) |
557 |
self.assertEqual(b'James Westby <jw+debian@jameswestby.net>', c.author) |
558 |
self.assertEqual(b'James Westby <jw+debian@jameswestby.net>', |
559 |
c.committer) |
560 |
self.assertEqual(b'd80c186a03f423a81b39df39dc87fd269736ca86', c.tree) |
561 |
self.assertEqual([b'ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd', |
562 |
b'4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'],
|
563 |
c.parents) |
564 |
expected_time = datetime.datetime(2007, 3, 24, 22, 1, 59) |
565 |
self.assertEqual(expected_time,
|
566 |
datetime.datetime.utcfromtimestamp(c.commit_time)) |
567 |
self.assertEqual(0, c.commit_timezone) |
568 |
self.assertEqual(expected_time,
|
569 |
datetime.datetime.utcfromtimestamp(c.author_time)) |
570 |
self.assertEqual(0, c.author_timezone) |
571 |
self.assertEqual(None, c.encoding) |
572 |
|
573 |
def test_custom(self): |
574 |
c = Commit.from_string(self.make_commit_text(
|
575 |
extra={b'extra-field': b'data'})) |
576 |
self.assertEqual([(b'extra-field', b'data')], c.extra) |
577 |
|
578 |
def test_encoding(self): |
579 |
c = Commit.from_string(self.make_commit_text(encoding=b'UTF-8')) |
580 |
self.assertEqual(b'UTF-8', c.encoding) |
581 |
|
582 |
def test_check(self): |
583 |
self.assertCheckSucceeds(Commit, self.make_commit_text()) |
584 |
self.assertCheckSucceeds(Commit, self.make_commit_text(parents=None)) |
585 |
self.assertCheckSucceeds(Commit,
|
586 |
self.make_commit_text(encoding=b'UTF-8')) |
587 |
|
588 |
self.assertCheckFails(Commit, self.make_commit_text(tree=b'xxx')) |
589 |
self.assertCheckFails(Commit, self.make_commit_text( |
590 |
parents=[a_sha, b'xxx']))
|
591 |
bad_committer = b'some guy without an email address 1174773719 +0000'
|
592 |
self.assertCheckFails(Commit,
|
593 |
self.make_commit_text(committer=bad_committer))
|
594 |
self.assertCheckFails(Commit,
|
595 |
self.make_commit_text(author=bad_committer))
|
596 |
self.assertCheckFails(Commit, self.make_commit_text(author=None)) |
597 |
self.assertCheckFails(Commit, self.make_commit_text(committer=None)) |
598 |
self.assertCheckFails(Commit, self.make_commit_text( |
599 |
author=None, committer=None)) |
600 |
|
601 |
def test_check_duplicates(self): |
602 |
# duplicate each of the header fields
|
603 |
for i in range(5): |
604 |
lines = self.make_commit_lines(parents=[a_sha], encoding=b'UTF-8') |
605 |
lines.insert(i, lines[i]) |
606 |
text = b'\n'.join(lines)
|
607 |
if lines[i].startswith(b'parent'): |
608 |
# duplicate parents are ok for now
|
609 |
self.assertCheckSucceeds(Commit, text)
|
610 |
else:
|
611 |
self.assertCheckFails(Commit, text)
|
612 |
|
613 |
def test_check_order(self): |
614 |
lines = self.make_commit_lines(parents=[a_sha], encoding=b'UTF-8') |
615 |
headers = lines[:5]
|
616 |
rest = lines[5:]
|
617 |
# of all possible permutations, ensure only the original succeeds
|
618 |
for perm in permutations(headers): |
619 |
perm = list(perm)
|
620 |
text = b'\n'.join(perm + rest)
|
621 |
if perm == headers:
|
622 |
self.assertCheckSucceeds(Commit, text)
|
623 |
else:
|
624 |
self.assertCheckFails(Commit, text)
|
625 |
|
626 |
def test_parse_gpgsig(self): |
627 |
c = Commit.from_string(b"""tree aaff74984cccd156a469afa7d9ab10e4777beb24
|
628 |
author Jelmer Vernooij <jelmer@samba.org> 1412179807 +0200
|
629 |
committer Jelmer Vernooij <jelmer@samba.org> 1412179807 +0200
|
630 |
gpgsig -----BEGIN PGP SIGNATURE-----
|
631 |
Version: GnuPG v1
|
632 |
|
633 |
iQIcBAABCgAGBQJULCdfAAoJEACAbyvXKaRXuKwP/RyP9PA49uAvu8tQVCC/uBa8
|
634 |
vi975+xvO14R8Pp8k2nps7lSxCdtCd+xVT1VRHs0wNhOZo2YCVoU1HATkPejqSeV
|
635 |
NScTHcxnk4/+bxyfk14xvJkNp7FlQ3npmBkA+lbV0Ubr33rvtIE5jiJPyz+SgWAg
|
636 |
xdBG2TojV0squj00GoH/euK6aX7GgZtwdtpTv44haCQdSuPGDcI4TORqR6YSqvy3
|
637 |
GPE+3ZqXPFFb+KILtimkxitdwB7CpwmNse2vE3rONSwTvi8nq3ZoQYNY73CQGkUy
|
638 |
qoFU0pDtw87U3niFin1ZccDgH0bB6624sLViqrjcbYJeg815Htsu4rmzVaZADEVC
|
639 |
XhIO4MThebusdk0AcNGjgpf3HRHk0DPMDDlIjm+Oao0cqovvF6VyYmcb0C+RmhJj
|
640 |
dodLXMNmbqErwTk3zEkW0yZvNIYXH7m9SokPCZa4eeIM7be62X6h1mbt0/IU6Th+
|
641 |
v18fS0iTMP/Viug5und+05C/v04kgDo0CPphAbXwWMnkE4B6Tl9sdyUYXtvQsL7x
|
642 |
0+WP1gL27ANqNZiI07Kz/BhbBAQI/+2TFT7oGr0AnFPQ5jHp+3GpUf6OKuT1wT3H
|
643 |
ND189UFuRuubxb42vZhpcXRbqJVWnbECTKVUPsGZqat3enQUB63uM4i6/RdONDZA
|
644 |
fDeF1m4qYs+cUXKNUZ03
|
645 |
=X6RT
|
646 |
-----END PGP SIGNATURE-----
|
647 |
|
648 |
foo
|
649 |
""")
|
650 |
self.assertEqual(b'foo\n', c.message) |
651 |
self.assertEqual([], c.extra)
|
652 |
self.assertEqual(b"""-----BEGIN PGP SIGNATURE----- |
653 |
Version: GnuPG v1
|
654 |
|
655 |
iQIcBAABCgAGBQJULCdfAAoJEACAbyvXKaRXuKwP/RyP9PA49uAvu8tQVCC/uBa8
|
656 |
vi975+xvO14R8Pp8k2nps7lSxCdtCd+xVT1VRHs0wNhOZo2YCVoU1HATkPejqSeV
|
657 |
NScTHcxnk4/+bxyfk14xvJkNp7FlQ3npmBkA+lbV0Ubr33rvtIE5jiJPyz+SgWAg
|
658 |
xdBG2TojV0squj00GoH/euK6aX7GgZtwdtpTv44haCQdSuPGDcI4TORqR6YSqvy3
|
659 |
GPE+3ZqXPFFb+KILtimkxitdwB7CpwmNse2vE3rONSwTvi8nq3ZoQYNY73CQGkUy
|
660 |
qoFU0pDtw87U3niFin1ZccDgH0bB6624sLViqrjcbYJeg815Htsu4rmzVaZADEVC
|
661 |
XhIO4MThebusdk0AcNGjgpf3HRHk0DPMDDlIjm+Oao0cqovvF6VyYmcb0C+RmhJj
|
662 |
dodLXMNmbqErwTk3zEkW0yZvNIYXH7m9SokPCZa4eeIM7be62X6h1mbt0/IU6Th+
|
663 |
v18fS0iTMP/Viug5und+05C/v04kgDo0CPphAbXwWMnkE4B6Tl9sdyUYXtvQsL7x
|
664 |
0+WP1gL27ANqNZiI07Kz/BhbBAQI/+2TFT7oGr0AnFPQ5jHp+3GpUf6OKuT1wT3H
|
665 |
ND189UFuRuubxb42vZhpcXRbqJVWnbECTKVUPsGZqat3enQUB63uM4i6/RdONDZA
|
666 |
fDeF1m4qYs+cUXKNUZ03
|
667 |
=X6RT
|
668 |
-----END PGP SIGNATURE-----""", c.gpgsig)
|
669 |
|
670 |
|
671 |
_TREE_ITEMS = { |
672 |
b'a.c': (0o100755, b'd80c186a03f423a81b39df39dc87fd269736ca86'), |
673 |
b'a': (stat.S_IFDIR, b'd80c186a03f423a81b39df39dc87fd269736ca86'), |
674 |
b'a/c': (stat.S_IFDIR, b'd80c186a03f423a81b39df39dc87fd269736ca86'), |
675 |
} |
676 |
|
677 |
_SORTED_TREE_ITEMS = [ |
678 |
TreeEntry(b'a.c', 0o100755, b'd80c186a03f423a81b39df39dc87fd269736ca86'), |
679 |
TreeEntry(b'a', stat.S_IFDIR, b'd80c186a03f423a81b39df39dc87fd269736ca86'), |
680 |
TreeEntry(b'a/c', stat.S_IFDIR, b'd80c186a03f423a81b39df39dc87fd269736ca86'), |
681 |
] |
682 |
|
683 |
|
684 |
class TreeTests(ShaFileCheckTests): |
685 |
|
686 |
def test_add(self): |
687 |
myhexsha = b'd80c186a03f423a81b39df39dc87fd269736ca86'
|
688 |
x = Tree() |
689 |
x.add(b'myname', 0o100755, myhexsha) |
690 |
self.assertEqual(x[b'myname'], (0o100755, myhexsha)) |
691 |
self.assertEqual(b'100755 myname\0' + hex_to_sha(myhexsha), |
692 |
x.as_raw_string()) |
693 |
|
694 |
def test_add_old_order(self): |
695 |
myhexsha = b'd80c186a03f423a81b39df39dc87fd269736ca86'
|
696 |
x = Tree() |
697 |
warnings.simplefilter("ignore", DeprecationWarning) |
698 |
try:
|
699 |
x.add(0o100755, b'myname', myhexsha) |
700 |
finally:
|
701 |
warnings.resetwarnings() |
702 |
self.assertEqual(x[b'myname'], (0o100755, myhexsha)) |
703 |
self.assertEqual(b'100755 myname\0' + hex_to_sha(myhexsha), |
704 |
x.as_raw_string()) |
705 |
|
706 |
def test_simple(self): |
707 |
myhexsha = b'd80c186a03f423a81b39df39dc87fd269736ca86'
|
708 |
x = Tree() |
709 |
x[b'myname'] = (0o100755, myhexsha) |
710 |
self.assertEqual(b'100755 myname\0' + hex_to_sha(myhexsha), |
711 |
x.as_raw_string()) |
712 |
|
713 |
def test_tree_update_id(self): |
714 |
x = Tree() |
715 |
x[b'a.c'] = (0o100755, b'd80c186a03f423a81b39df39dc87fd269736ca86') |
716 |
self.assertEqual(b'0c5c6bc2c081accfbc250331b19e43b904ab9cdd', x.id) |
717 |
x[b'a.b'] = (stat.S_IFDIR, b'd80c186a03f423a81b39df39dc87fd269736ca86') |
718 |
self.assertEqual(b'07bfcb5f3ada15bbebdfa3bbb8fd858a363925c8', x.id) |
719 |
|
720 |
def test_tree_iteritems_dir_sort(self): |
721 |
x = Tree() |
722 |
for name, item in _TREE_ITEMS.items(): |
723 |
x[name] = item |
724 |
self.assertEqual(_SORTED_TREE_ITEMS, x.items())
|
725 |
|
726 |
def test_tree_items_dir_sort(self): |
727 |
x = Tree() |
728 |
for name, item in _TREE_ITEMS.items(): |
729 |
x[name] = item |
730 |
self.assertEqual(_SORTED_TREE_ITEMS, x.items())
|
731 |
|
732 |
def _do_test_parse_tree(self, parse_tree): |
733 |
dir = os.path.join(os.path.dirname(__file__), 'data', 'trees') |
734 |
o = Tree.from_path(hex_to_filename(dir, tree_sha))
|
735 |
self.assertEqual([(b'a', 0o100644, a_sha), (b'b', 0o100644, b_sha)], |
736 |
list(parse_tree(o.as_raw_string())))
|
737 |
# test a broken tree that has a leading 0 on the file mode
|
738 |
broken_tree = b'0100644 foo\0' + hex_to_sha(a_sha)
|
739 |
|
740 |
def eval_parse_tree(*args, **kwargs): |
741 |
return list(parse_tree(*args, **kwargs)) |
742 |
|
743 |
self.assertEqual([(b'foo', 0o100644, a_sha)], |
744 |
eval_parse_tree(broken_tree)) |
745 |
self.assertRaises(ObjectFormatException,
|
746 |
eval_parse_tree, broken_tree, strict=True)
|
747 |
|
748 |
test_parse_tree = functest_builder(_do_test_parse_tree, _parse_tree_py) |
749 |
test_parse_tree_extension = ext_functest_builder(_do_test_parse_tree, |
750 |
parse_tree) |
751 |
|
752 |
def _do_test_sorted_tree_items(self, sorted_tree_items): |
753 |
def do_sort(entries): |
754 |
return list(sorted_tree_items(entries, False)) |
755 |
|
756 |
actual = do_sort(_TREE_ITEMS) |
757 |
self.assertEqual(_SORTED_TREE_ITEMS, actual)
|
758 |
self.assertTrue(isinstance(actual[0], TreeEntry)) |
759 |
|
760 |
# C/Python implementations may differ in specific error types, but
|
761 |
# should all error on invalid inputs.
|
762 |
# For example, the C implementation has stricter type checks, so may
|
763 |
# raise TypeError where the Python implementation raises AttributeError.
|
764 |
errors = (TypeError, ValueError, AttributeError) |
765 |
self.assertRaises(errors, do_sort, b'foo') |
766 |
self.assertRaises(errors, do_sort, {b'foo': (1, 2, 3)}) |
767 |
|
768 |
myhexsha = b'd80c186a03f423a81b39df39dc87fd269736ca86'
|
769 |
self.assertRaises(errors, do_sort, {b'foo': (b'xxx', myhexsha)}) |
770 |
self.assertRaises(errors, do_sort, {b'foo': (0o100755, 12345)}) |
771 |
|
772 |
test_sorted_tree_items = functest_builder(_do_test_sorted_tree_items, |
773 |
_sorted_tree_items_py) |
774 |
test_sorted_tree_items_extension = ext_functest_builder( |
775 |
_do_test_sorted_tree_items, sorted_tree_items) |
776 |
|
777 |
def _do_test_sorted_tree_items_name_order(self, sorted_tree_items): |
778 |
self.assertEqual([
|
779 |
TreeEntry(b'a', stat.S_IFDIR,
|
780 |
b'd80c186a03f423a81b39df39dc87fd269736ca86'),
|
781 |
TreeEntry(b'a.c', 0o100755, |
782 |
b'd80c186a03f423a81b39df39dc87fd269736ca86'),
|
783 |
TreeEntry(b'a/c', stat.S_IFDIR,
|
784 |
b'd80c186a03f423a81b39df39dc87fd269736ca86'),
|
785 |
], list(sorted_tree_items(_TREE_ITEMS, True))) |
786 |
|
787 |
test_sorted_tree_items_name_order = functest_builder( |
788 |
_do_test_sorted_tree_items_name_order, _sorted_tree_items_py) |
789 |
test_sorted_tree_items_name_order_extension = ext_functest_builder( |
790 |
_do_test_sorted_tree_items_name_order, sorted_tree_items) |
791 |
|
792 |
def test_check(self): |
793 |
t = Tree |
794 |
sha = hex_to_sha(a_sha) |
795 |
|
796 |
# filenames
|
797 |
self.assertCheckSucceeds(t, b'100644 .a\0' + sha) |
798 |
self.assertCheckFails(t, b'100644 \0' + sha) |
799 |
self.assertCheckFails(t, b'100644 .\0' + sha) |
800 |
self.assertCheckFails(t, b'100644 a/a\0' + sha) |
801 |
self.assertCheckFails(t, b'100644 ..\0' + sha) |
802 |
|
803 |
# modes
|
804 |
self.assertCheckSucceeds(t, b'100644 a\0' + sha) |
805 |
self.assertCheckSucceeds(t, b'100755 a\0' + sha) |
806 |
self.assertCheckSucceeds(t, b'160000 a\0' + sha) |
807 |
# TODO more whitelisted modes
|
808 |
self.assertCheckFails(t, b'123456 a\0' + sha) |
809 |
self.assertCheckFails(t, b'123abc a\0' + sha) |
810 |
# should fail check, but parses ok
|
811 |
self.assertCheckFails(t, b'0100644 foo\0' + sha) |
812 |
|
813 |
# shas
|
814 |
self.assertCheckFails(t, b'100644 a\0' + (b'x' * 5)) |
815 |
self.assertCheckFails(t, b'100644 a\0' + (b'x' * 18) + b'\0') |
816 |
self.assertCheckFails(t, b'100644 a\0' + (b'x' * 21) + b'\n100644 b\0' + sha) |
817 |
|
818 |
# ordering
|
819 |
sha2 = hex_to_sha(b_sha) |
820 |
self.assertCheckSucceeds(t, b'100644 a\0' + sha + b'\n100644 b\0' + sha) |
821 |
self.assertCheckSucceeds(t, b'100644 a\0' + sha + b'\n100644 b\0' + sha2) |
822 |
self.assertCheckFails(t, b'100644 a\0' + sha + b'\n100755 a\0' + sha2) |
823 |
self.assertCheckFails(t, b'100644 b\0' + sha2 + b'\n100644 a\0' + sha) |
824 |
|
825 |
def test_iter(self): |
826 |
t = Tree() |
827 |
t[b'foo'] = (0o100644, a_sha) |
828 |
self.assertEqual(set([b'foo']), set(t)) |
829 |
|
830 |
|
831 |
class TagSerializeTests(TestCase): |
832 |
|
833 |
def test_serialize_simple(self): |
834 |
x = make_object(Tag, |
835 |
tagger=b'Jelmer Vernooij <jelmer@samba.org>',
|
836 |
name=b'0.1',
|
837 |
message=b'Tag 0.1',
|
838 |
object=(Blob, b'd80c186a03f423a81b39df39dc87fd269736ca86'),
|
839 |
tag_time=423423423,
|
840 |
tag_timezone=0)
|
841 |
self.assertEqual((b'object d80c186a03f423a81b39df39dc87fd269736ca86\n' |
842 |
b'type blob\n'
|
843 |
b'tag 0.1\n'
|
844 |
b'tagger Jelmer Vernooij <jelmer@samba.org> '
|
845 |
b'423423423 +0000\n'
|
846 |
b'\n'
|
847 |
b'Tag 0.1'), x.as_raw_string())
|
848 |
|
849 |
def test_serialize_none_message(self): |
850 |
x = make_object(Tag, |
851 |
tagger=b'Jelmer Vernooij <jelmer@samba.org>',
|
852 |
name=b'0.1',
|
853 |
message=None,
|
854 |
object=(Blob, b'd80c186a03f423a81b39df39dc87fd269736ca86'),
|
855 |
tag_time=423423423,
|
856 |
tag_timezone=0)
|
857 |
self.assertEqual((b'object d80c186a03f423a81b39df39dc87fd269736ca86\n' |
858 |
b'type blob\n'
|
859 |
b'tag 0.1\n'
|
860 |
b'tagger Jelmer Vernooij <jelmer@samba.org> '
|
861 |
b'423423423 +0000\n'), x.as_raw_string())
|
862 |
|
863 |
|
864 |
default_tagger = (b'Linus Torvalds <torvalds@woody.linux-foundation.org> '
|
865 |
b'1183319674 -0700')
|
866 |
default_message = b"""Linux 2.6.22-rc7
|
867 |
-----BEGIN PGP SIGNATURE-----
|
868 |
Version: GnuPG v1.4.7 (GNU/Linux)
|
869 |
|
870 |
iD8DBQBGiAaAF3YsRnbiHLsRAitMAKCiLboJkQECM/jpYsY3WPfvUgLXkACgg3ql
|
871 |
OK2XeQOiEeXtT76rV4t2WR4=
|
872 |
=ivrA
|
873 |
-----END PGP SIGNATURE-----
|
874 |
"""
|
875 |
|
876 |
|
877 |
class TagParseTests(ShaFileCheckTests): |
878 |
|
879 |
def make_tag_lines(self, |
880 |
object_sha=b'a38d6181ff27824c79fc7df825164a212eff6a3f',
|
881 |
object_type_name=b'commit',
|
882 |
name=b'v2.6.22-rc7',
|
883 |
tagger=default_tagger, |
884 |
message=default_message): |
885 |
lines = [] |
886 |
if object_sha is not None: |
887 |
lines.append(b'object ' + object_sha)
|
888 |
if object_type_name is not None: |
889 |
lines.append(b'type ' + object_type_name)
|
890 |
if name is not None: |
891 |
lines.append(b'tag ' + name)
|
892 |
if tagger is not None: |
893 |
lines.append(b'tagger ' + tagger)
|
894 |
if message is not None: |
895 |
lines.append(b'')
|
896 |
lines.append(message) |
897 |
return lines
|
898 |
|
899 |
def make_tag_text(self, **kwargs): |
900 |
return b'\n'.join(self.make_tag_lines(**kwargs)) |
901 |
|
902 |
def test_parse(self): |
903 |
x = Tag() |
904 |
x.set_raw_string(self.make_tag_text())
|
905 |
self.assertEqual(
|
906 |
b'Linus Torvalds <torvalds@woody.linux-foundation.org>', x.tagger)
|
907 |
self.assertEqual(b'v2.6.22-rc7', x.name) |
908 |
object_type, object_sha = x.object |
909 |
self.assertEqual(b'a38d6181ff27824c79fc7df825164a212eff6a3f', |
910 |
object_sha) |
911 |
self.assertEqual(Commit, object_type)
|
912 |
self.assertEqual(datetime.datetime.utcfromtimestamp(x.tag_time),
|
913 |
datetime.datetime(2007, 7, 1, 19, 54, 34)) |
914 |
self.assertEqual(-25200, x.tag_timezone) |
915 |
|
916 |
def test_parse_no_tagger(self): |
917 |
x = Tag() |
918 |
x.set_raw_string(self.make_tag_text(tagger=None)) |
919 |
self.assertEqual(None, x.tagger) |
920 |
self.assertEqual(b'v2.6.22-rc7', x.name) |
921 |
|
922 |
def test_parse_no_message(self): |
923 |
x = Tag() |
924 |
x.set_raw_string(self.make_tag_text(message=None)) |
925 |
self.assertEqual(None, x.message) |
926 |
self.assertEqual(
|
927 |
b'Linus Torvalds <torvalds@woody.linux-foundation.org>', x.tagger)
|
928 |
self.assertEqual(datetime.datetime.utcfromtimestamp(x.tag_time),
|
929 |
datetime.datetime(2007, 7, 1, 19, 54, 34)) |
930 |
self.assertEqual(-25200, x.tag_timezone) |
931 |
self.assertEqual(b'v2.6.22-rc7', x.name) |
932 |
|
933 |
def test_check(self): |
934 |
self.assertCheckSucceeds(Tag, self.make_tag_text()) |
935 |
self.assertCheckFails(Tag, self.make_tag_text(object_sha=None)) |
936 |
self.assertCheckFails(Tag, self.make_tag_text(object_type_name=None)) |
937 |
self.assertCheckFails(Tag, self.make_tag_text(name=None)) |
938 |
self.assertCheckFails(Tag, self.make_tag_text(name=b'')) |
939 |
self.assertCheckFails(Tag, self.make_tag_text( |
940 |
object_type_name=b'foobar'))
|
941 |
self.assertCheckFails(Tag, self.make_tag_text( |
942 |
tagger=b'some guy without an email address 1183319674 -0700'))
|
943 |
self.assertCheckFails(Tag, self.make_tag_text( |
944 |
tagger=(b'Linus Torvalds <torvalds@woody.linux-foundation.org> '
|
945 |
b'Sun 7 Jul 2007 12:54:34 +0700')))
|
946 |
self.assertCheckFails(Tag, self.make_tag_text(object_sha=b'xxx')) |
947 |
|
948 |
def test_check_duplicates(self): |
949 |
# duplicate each of the header fields
|
950 |
for i in range(4): |
951 |
lines = self.make_tag_lines()
|
952 |
lines.insert(i, lines[i]) |
953 |
self.assertCheckFails(Tag, b'\n'.join(lines)) |
954 |
|
955 |
def test_check_order(self): |
956 |
lines = self.make_tag_lines()
|
957 |
headers = lines[:4]
|
958 |
rest = lines[4:]
|
959 |
# of all possible permutations, ensure only the original succeeds
|
960 |
for perm in permutations(headers): |
961 |
perm = list(perm)
|
962 |
text = b'\n'.join(perm + rest)
|
963 |
if perm == headers:
|
964 |
self.assertCheckSucceeds(Tag, text)
|
965 |
else:
|
966 |
self.assertCheckFails(Tag, text)
|
967 |
|
968 |
def test_tree_copy_after_update(self): |
969 |
"""Check Tree.id is correctly updated when the tree is copied after updated.
|
970 |
"""
|
971 |
shas = [] |
972 |
tree = Tree() |
973 |
shas.append(tree.id) |
974 |
tree.add(b'data', 0o644, Blob().id) |
975 |
copied = tree.copy() |
976 |
shas.append(tree.id) |
977 |
shas.append(copied.id) |
978 |
|
979 |
self.assertNotIn(shas[0], shas[1:]) |
980 |
self.assertEqual(shas[1], shas[2]) |
981 |
|
982 |
|
983 |
class CheckTests(TestCase): |
984 |
|
985 |
def test_check_hexsha(self): |
986 |
check_hexsha(a_sha, "failed to check good sha")
|
987 |
self.assertRaises(ObjectFormatException, check_hexsha, b'1' * 39, |
988 |
'sha too short')
|
989 |
self.assertRaises(ObjectFormatException, check_hexsha, b'1' * 41, |
990 |
'sha too long')
|
991 |
self.assertRaises(ObjectFormatException, check_hexsha, b'x' * 40, |
992 |
'invalid characters')
|
993 |
|
994 |
def test_check_identity(self): |
995 |
check_identity(b'Dave Borowitz <dborowitz@google.com>',
|
996 |
"failed to check good identity")
|
997 |
check_identity(b'<dborowitz@google.com>',
|
998 |
"failed to check good identity")
|
999 |
self.assertRaises(ObjectFormatException, check_identity,
|
1000 |
b'Dave Borowitz', "no email") |
1001 |
self.assertRaises(ObjectFormatException, check_identity,
|
1002 |
b'Dave Borowitz <dborowitz', "incomplete email") |
1003 |
self.assertRaises(ObjectFormatException, check_identity,
|
1004 |
b'dborowitz@google.com>', "incomplete email") |
1005 |
self.assertRaises(ObjectFormatException, check_identity,
|
1006 |
b'Dave Borowitz <<dborowitz@google.com>', "typo") |
1007 |
self.assertRaises(ObjectFormatException, check_identity,
|
1008 |
b'Dave Borowitz <dborowitz@google.com>>', "typo") |
1009 |
self.assertRaises(ObjectFormatException, check_identity,
|
1010 |
b'Dave Borowitz <dborowitz@google.com>xxx',
|
1011 |
"trailing characters")
|
1012 |
|
1013 |
|
1014 |
class TimezoneTests(TestCase): |
1015 |
|
1016 |
def test_parse_timezone_utc(self): |
1017 |
self.assertEqual((0, False), parse_timezone(b'+0000')) |
1018 |
|
1019 |
def test_parse_timezone_utc_negative(self): |
1020 |
self.assertEqual((0, True), parse_timezone(b'-0000')) |
1021 |
|
1022 |
def test_generate_timezone_utc(self): |
1023 |
self.assertEqual(b'+0000', format_timezone(0)) |
1024 |
|
1025 |
def test_generate_timezone_utc_negative(self): |
1026 |
self.assertEqual(b'-0000', format_timezone(0, True)) |
1027 |
|
1028 |
def test_parse_timezone_cet(self): |
1029 |
self.assertEqual((60 * 60, False), parse_timezone(b'+0100')) |
1030 |
|
1031 |
def test_format_timezone_cet(self): |
1032 |
self.assertEqual(b'+0100', format_timezone(60 * 60)) |
1033 |
|
1034 |
def test_format_timezone_pdt(self): |
1035 |
self.assertEqual(b'-0400', format_timezone(-4 * 60 * 60)) |
1036 |
|
1037 |
def test_parse_timezone_pdt(self): |
1038 |
self.assertEqual((-4 * 60 * 60, False), parse_timezone(b'-0400')) |
1039 |
|
1040 |
def test_format_timezone_pdt_half(self): |
1041 |
self.assertEqual(b'-0440', |
1042 |
format_timezone(int(((-4 * 60) - 40) * 60))) |
1043 |
|
1044 |
def test_format_timezone_double_negative(self): |
1045 |
self.assertEqual(b'--700', |
1046 |
format_timezone(int(((7 * 60)) * 60), True)) |
1047 |
|
1048 |
def test_parse_timezone_pdt_half(self): |
1049 |
self.assertEqual((((-4 * 60) - 40) * 60, False), |
1050 |
parse_timezone(b'-0440'))
|
1051 |
|
1052 |
def test_parse_timezone_double_negative(self): |
1053 |
self.assertEqual(
|
1054 |
(int(((7 * 60)) * 60), False), parse_timezone(b'+700')) |
1055 |
self.assertEqual(
|
1056 |
(int(((7 * 60)) * 60), True), parse_timezone(b'--700')) |
1057 |
|
1058 |
|
1059 |
class ShaFileCopyTests(TestCase): |
1060 |
|
1061 |
def assert_copy(self, orig): |
1062 |
oclass = object_class(orig.type_num) |
1063 |
|
1064 |
copy = orig.copy() |
1065 |
self.assertTrue(isinstance(copy, oclass)) |
1066 |
self.assertEqual(copy, orig)
|
1067 |
self.assertTrue(copy is not orig) |
1068 |
|
1069 |
def test_commit_copy(self): |
1070 |
attrs = {'tree': b'd80c186a03f423a81b39df39dc87fd269736ca86', |
1071 |
'parents': [b'ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd', |
1072 |
b'4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'],
|
1073 |
'author': b'James Westby <jw+debian@jameswestby.net>', |
1074 |
'committer': b'James Westby <jw+debian@jameswestby.net>', |
1075 |
'commit_time': 1174773719, |
1076 |
'author_time': 1174773719, |
1077 |
'commit_timezone': 0, |
1078 |
'author_timezone': 0, |
1079 |
'message': b'Merge ../b\n'} |
1080 |
commit = make_commit(**attrs) |
1081 |
self.assert_copy(commit)
|
1082 |
|
1083 |
def test_blob_copy(self): |
1084 |
blob = make_object(Blob, data=b'i am a blob')
|
1085 |
self.assert_copy(blob)
|
1086 |
|
1087 |
def test_tree_copy(self): |
1088 |
blob = make_object(Blob, data=b'i am a blob')
|
1089 |
tree = Tree() |
1090 |
tree[b'blob'] = (stat.S_IFREG, blob.id)
|
1091 |
self.assert_copy(tree)
|
1092 |
|
1093 |
def test_tag_copy(self): |
1094 |
tag = make_object( |
1095 |
Tag, name=b'tag', message=b'', |
1096 |
tagger=b'Tagger <test@example.com>',
|
1097 |
tag_time=12345, tag_timezone=0, |
1098 |
object=(Commit, b'0' * 40)) |
1099 |
self.assert_copy(tag)
|
1100 |
|
1101 |
|
1102 |
class ShaFileSerializeTests(TestCase): |
1103 |
"""
|
1104 |
Test that `ShaFile` objects only gets serialized once if they haven't changed.
|
1105 |
"""
|
1106 |
|
1107 |
@contextmanager
|
1108 |
def assert_serialization_on_change(self, obj, needs_serialization_after_change=True): |
1109 |
old_id = obj.id |
1110 |
self.assertFalse(obj._needs_serialization)
|
1111 |
|
1112 |
yield obj
|
1113 |
|
1114 |
if needs_serialization_after_change:
|
1115 |
self.assertTrue(obj._needs_serialization)
|
1116 |
else:
|
1117 |
self.assertFalse(obj._needs_serialization)
|
1118 |
new_id = obj.id |
1119 |
self.assertFalse(obj._needs_serialization)
|
1120 |
self.assertNotEqual(old_id, new_id)
|
1121 |
|
1122 |
def test_commit_serialize(self): |
1123 |
attrs = {'tree': b'd80c186a03f423a81b39df39dc87fd269736ca86', |
1124 |
'parents': [b'ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd', |
1125 |
b'4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'],
|
1126 |
'author': b'James Westby <jw+debian@jameswestby.net>', |
1127 |
'committer': b'James Westby <jw+debian@jameswestby.net>', |
1128 |
'commit_time': 1174773719, |
1129 |
'author_time': 1174773719, |
1130 |
'commit_timezone': 0, |
1131 |
'author_timezone': 0, |
1132 |
'message': b'Merge ../b\n'} |
1133 |
commit = make_commit(**attrs) |
1134 |
|
1135 |
with self.assert_serialization_on_change(commit): |
1136 |
commit.parents = [b'ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd']
|
1137 |
|
1138 |
def test_blob_serialize(self): |
1139 |
blob = make_object(Blob, data=b'i am a blob')
|
1140 |
|
1141 |
with self.assert_serialization_on_change(blob, needs_serialization_after_change=False): |
1142 |
blob.data = b'i am another blob'
|
1143 |
|
1144 |
def test_tree_serialize(self): |
1145 |
blob = make_object(Blob, data=b'i am a blob')
|
1146 |
tree = Tree() |
1147 |
tree[b'blob'] = (stat.S_IFREG, blob.id)
|
1148 |
|
1149 |
with self.assert_serialization_on_change(tree): |
1150 |
tree[b'blob2'] = (stat.S_IFREG, blob.id)
|
1151 |
|
1152 |
def test_tag_serialize(self): |
1153 |
tag = make_object( |
1154 |
Tag, name=b'tag', message=b'', |
1155 |
tagger=b'Tagger <test@example.com>',
|
1156 |
tag_time=12345, tag_timezone=0, |
1157 |
object=(Commit, b'0' * 40)) |
1158 |
|
1159 |
with self.assert_serialization_on_change(tag): |
1160 |
tag.message = b'new message'
|
1161 |
|
1162 |
|
1163 |
class PrettyFormatTreeEntryTests(TestCase): |
1164 |
|
1165 |
def test_format(self): |
1166 |
self.assertEqual(
|
1167 |
'40000 tree 40820c38cfb182ce6c8b261555410d8382a5918b\tfoo\n',
|
1168 |
pretty_format_tree_entry(b"foo", 0o40000, |
1169 |
b"40820c38cfb182ce6c8b261555410d8382a5918b"))
|
1170 |
|