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 / compat / test_pack.py @ 959
History | View | Annotate | Download (6.36 KB)
1 |
# test_pack.py -- Compatibility tests for git packs.
|
---|---|
2 |
# Copyright (C) 2010 Google, Inc.
|
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 |
"""Compatibility tests for git packs."""
|
22 |
|
23 |
|
24 |
import binascii |
25 |
import os |
26 |
import re |
27 |
import shutil |
28 |
import tempfile |
29 |
|
30 |
from dulwich.pack import ( |
31 |
write_pack, |
32 |
) |
33 |
from dulwich.objects import ( |
34 |
Blob, |
35 |
) |
36 |
from dulwich.tests import ( |
37 |
SkipTest, |
38 |
) |
39 |
from dulwich.tests.test_pack import ( |
40 |
a_sha, |
41 |
pack1_sha, |
42 |
PackTests, |
43 |
) |
44 |
from dulwich.tests.compat.utils import ( |
45 |
require_git_version, |
46 |
run_git_or_fail, |
47 |
) |
48 |
|
49 |
_NON_DELTA_RE = re.compile(b'non delta: (?P<non_delta>\d+) objects')
|
50 |
|
51 |
def _git_verify_pack_object_list(output): |
52 |
pack_shas = set()
|
53 |
for line in output.splitlines(): |
54 |
sha = line[:40]
|
55 |
try:
|
56 |
binascii.unhexlify(sha) |
57 |
except (TypeError, binascii.Error): |
58 |
continue # non-sha line |
59 |
pack_shas.add(sha) |
60 |
return pack_shas
|
61 |
|
62 |
|
63 |
class TestPack(PackTests): |
64 |
"""Compatibility tests for reading and writing pack files."""
|
65 |
|
66 |
def setUp(self): |
67 |
require_git_version((1, 5, 0)) |
68 |
super(TestPack, self).setUp() |
69 |
self._tempdir = tempfile.mkdtemp()
|
70 |
self.addCleanup(shutil.rmtree, self._tempdir) |
71 |
|
72 |
def test_copy(self): |
73 |
with self.get_pack(pack1_sha) as origpack: |
74 |
self.assertSucceeds(origpack.index.check)
|
75 |
pack_path = os.path.join(self._tempdir, "Elch") |
76 |
write_pack(pack_path, origpack.pack_tuples()) |
77 |
output = run_git_or_fail(['verify-pack', '-v', pack_path]) |
78 |
orig_shas = set(o.id for o in origpack.iterobjects()) |
79 |
self.assertEqual(orig_shas, _git_verify_pack_object_list(output))
|
80 |
|
81 |
def test_deltas_work(self): |
82 |
with self.get_pack(pack1_sha) as orig_pack: |
83 |
orig_blob = orig_pack[a_sha] |
84 |
new_blob = Blob() |
85 |
new_blob.data = orig_blob.data + b'x'
|
86 |
all_to_pack = list(orig_pack.pack_tuples()) + [(new_blob, None)] |
87 |
pack_path = os.path.join(self._tempdir, 'pack_with_deltas') |
88 |
write_pack(pack_path, all_to_pack, deltify=True)
|
89 |
output = run_git_or_fail(['verify-pack', '-v', pack_path]) |
90 |
self.assertEqual(set(x[0].id for x in all_to_pack), |
91 |
_git_verify_pack_object_list(output)) |
92 |
# We specifically made a new blob that should be a delta
|
93 |
# against the blob a_sha, so make sure we really got only 3
|
94 |
# non-delta objects:
|
95 |
got_non_delta = int(_NON_DELTA_RE.search(output).group('non_delta')) |
96 |
self.assertEqual(
|
97 |
3, got_non_delta,
|
98 |
'Expected 3 non-delta objects, got %d' % got_non_delta)
|
99 |
|
100 |
def test_delta_medium_object(self): |
101 |
# This tests an object set that will have a copy operation
|
102 |
# 2**20 in size.
|
103 |
with self.get_pack(pack1_sha) as orig_pack: |
104 |
orig_blob = orig_pack[a_sha] |
105 |
new_blob = Blob() |
106 |
new_blob.data = orig_blob.data + (b'x' * 2 ** 20) |
107 |
new_blob_2 = Blob() |
108 |
new_blob_2.data = new_blob.data + b'y'
|
109 |
all_to_pack = list(orig_pack.pack_tuples()) + [(new_blob, None), |
110 |
(new_blob_2, None)]
|
111 |
pack_path = os.path.join(self._tempdir, 'pack_with_deltas') |
112 |
write_pack(pack_path, all_to_pack, deltify=True)
|
113 |
output = run_git_or_fail(['verify-pack', '-v', pack_path]) |
114 |
self.assertEqual(set(x[0].id for x in all_to_pack), |
115 |
_git_verify_pack_object_list(output)) |
116 |
# We specifically made a new blob that should be a delta
|
117 |
# against the blob a_sha, so make sure we really got only 3
|
118 |
# non-delta objects:
|
119 |
got_non_delta = int(_NON_DELTA_RE.search(output).group('non_delta')) |
120 |
self.assertEqual(
|
121 |
3, got_non_delta,
|
122 |
'Expected 3 non-delta objects, got %d' % got_non_delta)
|
123 |
# We expect one object to have a delta chain length of two
|
124 |
# (new_blob_2), so let's verify that actually happens:
|
125 |
self.assertIn(b'chain length = 2', output) |
126 |
|
127 |
# This test is SUPER slow: over 80 seconds on a 2012-era
|
128 |
# laptop. This is because SequenceMatcher is worst-case quadratic
|
129 |
# on the input size. It's impractical to produce deltas for
|
130 |
# objects this large, but it's still worth doing the right thing
|
131 |
# when it happens.
|
132 |
def test_delta_large_object(self): |
133 |
# This tests an object set that will have a copy operation
|
134 |
# 2**25 in size. This is a copy large enough that it requires
|
135 |
# two copy operations in git's binary delta format.
|
136 |
raise SkipTest('skipping slow, large test') |
137 |
with self.get_pack(pack1_sha) as orig_pack: |
138 |
new_blob = Blob() |
139 |
new_blob.data = 'big blob' + ('x' * 2 ** 25) |
140 |
new_blob_2 = Blob() |
141 |
new_blob_2.data = new_blob.data + 'y'
|
142 |
all_to_pack = list(orig_pack.pack_tuples()) + [(new_blob, None), |
143 |
(new_blob_2, None)]
|
144 |
pack_path = os.path.join(self._tempdir, "pack_with_deltas") |
145 |
write_pack(pack_path, all_to_pack, deltify=True)
|
146 |
output = run_git_or_fail(['verify-pack', '-v', pack_path]) |
147 |
self.assertEqual(set(x[0].id for x in all_to_pack), |
148 |
_git_verify_pack_object_list(output)) |
149 |
# We specifically made a new blob that should be a delta
|
150 |
# against the blob a_sha, so make sure we really got only 4
|
151 |
# non-delta objects:
|
152 |
got_non_delta = int(_NON_DELTA_RE.search(output).group('non_delta')) |
153 |
self.assertEqual(
|
154 |
4, got_non_delta,
|
155 |
'Expected 4 non-delta objects, got %d' % got_non_delta)
|