Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F9344863
test_converters.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
31 KB
Subscribers
None
test_converters.py
View Options
# Copyright (C) 2015-2022 The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information
import
copy
import
datetime
import
os
import
shutil
import
subprocess
import
tempfile
import
dulwich.objects
import
dulwich.repo
import
pytest
import
swh.loader.git.converters
as
converters
from
swh.model.hashutil
import
bytehex_to_hash
,
hash_to_bytehex
,
hash_to_bytes
from
swh.model.model
import
(
Content
,
Directory
,
DirectoryEntry
,
ObjectType
,
Person
,
Release
,
Revision
,
RevisionType
,
Timestamp
,
TimestampWithTimezone
,
)
TEST_DATA
=
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
"data"
)
GPGSIG
=
(
b
"-----BEGIN PGP SIGNATURE-----
\n
"
b
"
\n
"
b
"iQJLBAABCAA1FiEEAOWDevQbOk/9ITMF6ImSleOlnUcFAl8EnS4XHGRhdmlkLmRv
\n
"
b
"dWFyZEBzZGZhMy5vcmcACgkQ6ImSleOlnUdrqQ/8C5RO4NZ5Qr/dwAy2cPA7ktkY
\n
"
b
"1oUjKtspQoPbC1X3MXVa1aWo9B3KuOMR2URw44RhMNFwjccLOhfss06E8p7CZr2H
\n
"
b
"uR3CzdDw7i52jHLCL2M2ZMaPAEbQuHjXWiUWIUXz9So8YwpTyd2XQneyOC2RDDEI
\n
"
b
"I2NVbmiMeDz33jJYPrQO0QayW+ErW+xgBF7N/qS9jFWsdV1ZNfn9NxkTH8UdGuAX
\n
"
b
"583P+0tVC2DjXc6vORVhyFzyfn1A9wHosbtWI2Mpa+zezPjoPSkcyQAJu2GyOkMC
\n
"
b
"YzSjJdQVqyovo+INkIf6PuUNdp41886BG/06xwT8fl4sVsyO51lNIfgH0DMwfTTB
\n
"
b
"ZgThYnvvO7SrXDm3QzBTXkvAiHiFFl3iNyGkCyxvgVmaTntuFT+cP+HD/pCiGaC+
\n
"
b
"jHzRwfUrmuLd/lLPyq3JXBibyjnfd3SVS+7q1NZHJ4WUmCboZ0+pfrEl65mEQ/Hz
\n
"
b
"J1qCwQ/3SsTB77ANf6lLzGSowjjrtHcBTkTbFxR4ACUhiBbosyDKpHTM7fzGFGjo
\n
"
b
"EIjohzrEnqR3bbyxJkK+nxoOByhIRdowgyeJ02I4neMyLJqcaup8NMWCddxqjaPt
\n
"
b
"YobghnjaDqEd+suL/v83hbZUAZHNO3i1OZYGMqzp1WHikDPoTwGP76baqBoXi56T
\n
"
b
"4WSpxCAJRDODHLk1HgU=
\n
"
b
"=73wF"
b
"
\n
"
b
"-----END PGP SIGNATURE-----"
)
MERGETAG
=
(
b
"object 9768d0b576dbaaecd80abedad6dfd0d72f1476da
\n
"
b
"type commit
\n
"
b
"tag v0.0.1
\n
"
b
"tagger David Douard <david.douard@sdfa3.org> 1594138133 +0200
\n
"
b
"
\n
"
b
"v0.0.1
\n
"
b
"-----BEGIN PGP SIGNATURE-----
\n
"
b
"
\n
"
b
"iQJLBAABCAA1FiEEAOWDevQbOk/9ITMF6ImSleOlnUcFAl8EnhkXHGRhdmlkLmRv
\n
"
b
"dWFyZEBzZGZhMy5vcmcACgkQ6ImSleOlnUcdzg//ZW9y2xU5JFQuUsBe/LfKrs+m
\n
"
b
"0ohVInPKXwAfpB3+gn/XtTSLe+Nnr8+QEZyVRCUz2gpGZ2tNqRjhYLIX4x5KKlaV
\n
"
b
"rfl/6Cy7zibsxxuzA1h7HylCs3IPsueQpznVHUwD9jQ5baGJSc2Lt1LufXTueHZJ
\n
"
b
"Oc0oLiP5xCZcPqeX8R/4zUUImJZ1QrPeKmQ/3F+Iq62iWp7nWDp8PtwpykSiYlNf
\n
"
b
"KrJM8omGvrlrWLtfPNUaQFClXwnwK1/HyNY2kYan6K5NtsIl2UX0LZ42GkRjJIrb
\n
"
b
"q4TFIZWZ6xndtEhHEX6B8Q5TZV6sqPgNnfGpbhj8BDoZgjD0Y43fzfDiZ0Bl2tph
\n
"
b
"tXaLg3SX/UUjFVzC1zkoQ2MR7+j8NVKauAsBINpKF4pMGsrsVRk8764pgO49iQ+S
\n
"
b
"8JVCVV76dNNm1gd7BbhFAdIAiegBtsEF69niJBoHKYLlrT8E8hDkF/gk4IkimPqf
\n
"
b
"UHtw/fPhVW3B4G2skd013NJGcnRj5oKtaM99d2Roxc3vhSRiTsoaM8BM9NDvLmJg
\n
"
b
"35rWEOnet39iJIMCHk3AYaJl8QmUhllDdr6vygaBVeVEf27m2c3NzONmIKpWqa2J
\n
"
b
"kTpF4cmzHYro34G7WuJ1bYvmLb6qWNQt9wd8RW+J1kVm5I8dkjPzLUougBpOd0YL
\n
"
b
"Bl5UTQILbV4Tv8ZlmJM=
\n
"
b
"=s1lv
\n
"
b
"-----END PGP SIGNATURE-----"
)
class
SWHObjectType
:
"""Dulwich lookalike ObjectType class"""
def
__init__
(
self
,
type_name
):
self
.
type_name
=
type_name
@pytest.mark.fs
class
TestConverters
:
@classmethod
def
setup_class
(
cls
):
cls
.
repo_path
=
tempfile
.
mkdtemp
()
bundle
=
os
.
path
.
join
(
TEST_DATA
,
"git-repos"
,
"example-submodule.bundle"
)
git
=
subprocess
.
Popen
(
[
"git"
,
"clone"
,
"--quiet"
,
"--bare"
,
"--mirror"
,
bundle
,
cls
.
repo_path
],
cwd
=
TEST_DATA
,
)
# flush stdout of xz
git
.
communicate
()
cls
.
repo
=
dulwich
.
repo
.
Repo
(
cls
.
repo_path
)
@classmethod
def
tearDownClass
(
cls
):
super
()
.
tearDownClass
()
shutil
.
rmtree
(
cls
.
repo_path
)
def
test_blob_to_content
(
self
):
content_id
=
b
"28c6f4023d65f74e3b59a2dea3c4277ed9ee07b0"
content
=
converters
.
dulwich_blob_to_content
(
self
.
repo
[
content_id
])
expected_content
=
Content
(
sha1_git
=
bytehex_to_hash
(
content_id
),
sha1
=
hash_to_bytes
(
"4850a3420a2262ff061cb296fb915430fa92301c"
),
sha256
=
hash_to_bytes
(
"fee7c8a485a10321ad94b64135073cb5"
"5f22cb9f57fa2417d2adfb09d310adef"
),
blake2s256
=
hash_to_bytes
(
"5d71873f42a137f6d89286e43677721e574"
"1fa05ce4cd5e3c7ea7c44d4c2d10b"
),
data
=
(
b
'[submodule "example-dependency"]
\n
'
b
"
\t
path = example-dependency
\n
"
b
"
\t
url = https://github.com/githubtraining/"
b
"example-dependency.git
\n
"
),
length
=
124
,
status
=
"visible"
,
)
assert
content
==
expected_content
def
test_corrupt_blob
(
self
,
mocker
):
# has a signature
sha1
=
hash_to_bytes
(
"28c6f4023d65f74e3b59a2dea3c4277ed9ee07b0"
)
blob
=
copy
.
deepcopy
(
self
.
repo
[
hash_to_bytehex
(
sha1
)])
class
hasher
:
def
digest
():
return
sha1
blob
.
_sha
=
hasher
converters
.
dulwich_blob_to_content
(
blob
)
converters
.
dulwich_blob_to_content_id
(
blob
)
sha1
=
hash_to_bytes
(
"1234"
*
10
)
with
pytest
.
raises
(
converters
.
HashMismatch
):
converters
.
dulwich_blob_to_content
(
blob
)
with
pytest
.
raises
(
converters
.
HashMismatch
):
converters
.
dulwich_blob_to_content_id
(
blob
)
def
test_convertion_wrong_input
(
self
):
class
Something
:
type_name
=
b
"something-not-the-right-type"
m
=
{
"blob"
:
converters
.
dulwich_blob_to_content
,
"tree"
:
converters
.
dulwich_tree_to_directory
,
"commit"
:
converters
.
dulwich_tree_to_directory
,
"tag"
:
converters
.
dulwich_tag_to_release
,
}
for
_callable
in
m
.
values
():
with
pytest
.
raises
(
ValueError
):
_callable
(
Something
())
def
test_corrupt_tree
(
self
):
sha1
=
b
"a9b41fc6347d778f16c4380b598d8083e9b4c1fb"
target
=
b
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
tree
=
dulwich
.
objects
.
Tree
()
tree
.
add
(
b
"file1"
,
0
o644
,
target
)
assert
tree
.
sha
()
.
hexdigest
()
==
sha1
.
decode
()
converters
.
dulwich_tree_to_directory
(
tree
)
original_sha
=
tree
.
sha
()
tree
.
add
(
b
"file2"
,
0
o644
,
target
)
tree
.
sha
()
# reset tree._needs_serialization
tree
.
_sha
=
original_sha
# force the wrong hash
assert
tree
.
sha
()
.
hexdigest
()
==
sha1
.
decode
()
with
pytest
.
raises
(
converters
.
HashMismatch
):
converters
.
dulwich_tree_to_directory
(
tree
)
def
test_weird_tree
(
self
):
"""Tests a tree with entries the wrong order"""
raw_manifest
=
(
b
"0644 file2
\x00
"
b
"d
\x1f\xb6\xe0\x8d\xdb
.O
\xd0\x96\xdc\xf1\x8e\x80\xb8\x94\xbf
~%
\xce
"
b
"0644 file1
\x00
"
b
"d
\x1f\xb6\xe0\x8d\xdb
.O
\xd0\x96\xdc\xf1\x8e\x80\xb8\x94\xbf
~%
\xce
"
)
tree
=
dulwich
.
objects
.
Tree
.
from_raw_string
(
b
"tree"
,
raw_manifest
)
assert
converters
.
dulwich_tree_to_directory
(
tree
)
==
Directory
(
entries
=
(
# in alphabetical order, as it should be
DirectoryEntry
(
name
=
b
"file1"
,
type
=
"file"
,
target
=
hash_to_bytes
(
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
),
perms
=
0
o644
,
),
DirectoryEntry
(
name
=
b
"file2"
,
type
=
"file"
,
target
=
hash_to_bytes
(
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
),
perms
=
0
o644
,
),
),
raw_manifest
=
b
"tree 62
\x00
"
+
raw_manifest
,
)
def
test_tree_perms
(
self
):
entries
=
[
(
b
"blob_100644"
,
0
o100644
,
"file"
),
(
b
"blob_100664"
,
0
o100664
,
"file"
),
(
b
"blob_100666"
,
0
o100666
,
"file"
),
(
b
"blob_120000"
,
0
o120000
,
"file"
),
(
b
"commit_160644"
,
0
o160644
,
"rev"
),
(
b
"commit_160664"
,
0
o160664
,
"rev"
),
(
b
"commit_160666"
,
0
o160666
,
"rev"
),
(
b
"commit_normal"
,
0
o160000
,
"rev"
),
(
b
"tree_040644"
,
0
o040644
,
"dir"
),
(
b
"tree_040664"
,
0
o040664
,
"dir"
),
(
b
"tree_040666"
,
0
o040666
,
"dir"
),
(
b
"tree_normal"
,
0
o040000
,
"dir"
),
]
tree
=
dulwich
.
objects
.
Tree
()
for
(
name
,
mode
,
_
)
in
entries
:
tree
.
add
(
name
,
mode
,
b
"00"
*
20
)
assert
converters
.
dulwich_tree_to_directory
(
tree
)
==
Directory
(
entries
=
tuple
(
DirectoryEntry
(
type
=
type
,
perms
=
perms
,
name
=
name
,
target
=
b
"
\x00
"
*
20
)
for
(
name
,
perms
,
type
)
in
entries
)
)
def
test_commit_to_revision
(
self
):
sha1
=
b
"9768d0b576dbaaecd80abedad6dfd0d72f1476da"
revision
=
converters
.
dulwich_commit_to_revision
(
self
.
repo
[
sha1
])
expected_revision
=
Revision
(
id
=
hash_to_bytes
(
"9768d0b576dbaaecd80abedad6dfd0d72f1476da"
),
directory
=
b
"
\xf0
i
\\
./
\xa7\xce\x9d
W@#
\xc3
A7a
\xa4
s
\xe5\x00\xca
"
,
type
=
RevisionType
.
GIT
,
committer
=
Person
(
name
=
b
"Stefano Zacchiroli"
,
fullname
=
b
"Stefano Zacchiroli <zack@upsilon.cc>"
,
email
=
b
"zack@upsilon.cc"
,
),
author
=
Person
(
name
=
b
"Stefano Zacchiroli"
,
fullname
=
b
"Stefano Zacchiroli <zack@upsilon.cc>"
,
email
=
b
"zack@upsilon.cc"
,
),
committer_date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1443083765
,
microseconds
=
0
,
),
offset_bytes
=
b
"+0200"
,
),
message
=
b
"add submodule dependency
\n
"
,
metadata
=
None
,
extra_headers
=
(),
date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1443083765
,
microseconds
=
0
,
),
offset_bytes
=
b
"+0200"
,
),
parents
=
(
b
"
\xc3\xc5\x88
q23`
\x9f
[
\xbb\xb2\xd9\xe7\xf3\xfb
Jf
\x0f
?r"
,),
synthetic
=
False
,
)
assert
revision
==
expected_revision
def
test_commit_to_revision_with_extra_headers
(
self
):
sha1
=
b
"322f5bc915e50fc25e85226b5a182bded0e98e4b"
revision
=
converters
.
dulwich_commit_to_revision
(
self
.
repo
[
sha1
])
expected_revision
=
Revision
(
id
=
hash_to_bytes
(
sha1
.
decode
()),
directory
=
bytes
.
fromhex
(
"f8ec06e4ed7b9fff4918a0241a48023143f30000"
),
type
=
RevisionType
.
GIT
,
committer
=
Person
(
name
=
b
"David Douard"
,
fullname
=
b
"David Douard <david.douard@sdfa3.org>"
,
email
=
b
"david.douard@sdfa3.org"
,
),
author
=
Person
(
name
=
b
"David Douard"
,
fullname
=
b
"David Douard <david.douard@sdfa3.org>"
,
email
=
b
"david.douard@sdfa3.org"
,
),
committer_date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1594137902
,
microseconds
=
0
,
),
offset_bytes
=
b
"+0200"
,
),
message
=
b
"Am
\xe9
lioration du fichier READM
\xa4\n
"
,
metadata
=
None
,
extra_headers
=
((
b
"encoding"
,
b
"ISO-8859-15"
),
(
b
"gpgsig"
,
GPGSIG
)),
date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1594136900
,
microseconds
=
0
,
),
offset_bytes
=
b
"+0200"
,
),
parents
=
(
bytes
.
fromhex
(
"c730509025c6e81947102b2d77bc4dc1cade9489"
),),
synthetic
=
False
,
)
assert
revision
==
expected_revision
def
test_commit_without_manifest
(
self
):
"""Tests a Release can still be produced when the manifest is not understood
by the custom parser in dulwich_commit_to_revision."""
target
=
b
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
message
=
b
"some commit message"
author
=
Person
(
fullname
=
b
"Foo <foo@example.org>"
,
name
=
b
"Foo"
,
email
=
b
"foo@example.org"
)
commit
=
dulwich
.
objects
.
Commit
()
commit
.
tree
=
target
commit
.
message
=
message
commit
.
author
=
commit
.
committer
=
b
"Foo <foo@example.org>"
commit
.
author_time
=
commit
.
commit_time
=
1641980946
commit
.
author_timezone
=
commit
.
commit_timezone
=
3600
assert
converters
.
dulwich_commit_to_revision
(
commit
)
==
Revision
(
message
=
b
"some commit message"
,
author
=
author
,
committer
=
author
,
date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1641980946
,
microseconds
=
0
),
offset_bytes
=
b
"+0100"
,
),
committer_date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1641980946
,
microseconds
=
0
),
offset_bytes
=
b
"+0100"
,
),
type
=
RevisionType
.
GIT
,
directory
=
hash_to_bytes
(
target
.
decode
()),
synthetic
=
False
,
metadata
=
None
,
parents
=
(),
)
@pytest.mark.parametrize
(
"attribute"
,
[
"message"
,
"encoding"
,
"author"
,
"gpgsig"
])
def
test_corrupt_commit
(
self
,
attribute
):
sha
=
hash_to_bytes
(
"3f0ac5a6d15d89cf928209a57334e3b77c5651b9"
)
target
=
b
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
message
=
b
"some commit message"
commit
=
dulwich
.
objects
.
Commit
()
commit
.
tree
=
target
commit
.
message
=
message
commit
.
gpgsig
=
GPGSIG
commit
.
author
=
commit
.
committer
=
b
"Foo <foo@example.org>"
commit
.
author_time
=
commit
.
commit_time
=
1641980946
commit
.
author_timezone
=
commit
.
commit_timezone
=
3600
converters
.
dulwich_commit_to_revision
(
commit
)
assert
commit
.
sha
()
.
digest
()
==
sha
original_sha
=
commit
.
sha
()
setattr
(
commit
,
attribute
,
b
"abcde"
)
commit
.
sha
()
# reset tag._needs_serialization
commit
.
_sha
=
original_sha
# force the wrong hash
with
pytest
.
raises
(
converters
.
HashMismatch
):
converters
.
dulwich_commit_to_revision
(
commit
)
if
attribute
==
"_gpgsig"
:
setattr
(
commit
,
attribute
,
None
)
commit
.
sha
()
# reset tag._needs_serialization
commit
.
_sha
=
original_sha
# force the wrong hash
with
pytest
.
raises
(
converters
.
HashMismatch
):
converters
.
dulwich_commit_to_revision
(
commit
)
def
test_commit_to_revision_with_extra_headers_mergetag
(
self
):
sha1
=
b
"3ab3da4bf0f81407be16969df09cd1c8af9ac703"
revision
=
converters
.
dulwich_commit_to_revision
(
self
.
repo
[
sha1
])
expected_revision
=
Revision
(
id
=
hash_to_bytes
(
sha1
.
decode
()),
directory
=
bytes
.
fromhex
(
"faa4b64a841ca3e3f07d6501caebda2e3e8e544e"
),
type
=
RevisionType
.
GIT
,
committer
=
Person
(
name
=
b
"David Douard"
,
fullname
=
b
"David Douard <david.douard@sdfa3.org>"
,
email
=
b
"david.douard@sdfa3.org"
,
),
author
=
Person
(
name
=
b
"David Douard"
,
fullname
=
b
"David Douard <david.douard@sdfa3.org>"
,
email
=
b
"david.douard@sdfa3.org"
,
),
committer_date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1594138183
,
microseconds
=
0
,
),
offset_bytes
=
b
"+0200"
,
),
message
=
b
"Merge tag 'v0.0.1' into readme
\n\n
v0.0.1
\n
"
,
metadata
=
None
,
extra_headers
=
((
b
"encoding"
,
b
"ISO-8859-15"
),
(
b
"mergetag"
,
MERGETAG
)),
date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1594138183
,
microseconds
=
0
,
),
offset_bytes
=
b
"+0200"
,
),
parents
=
(
bytes
.
fromhex
(
"322f5bc915e50fc25e85226b5a182bded0e98e4b"
),
bytes
.
fromhex
(
"9768d0b576dbaaecd80abedad6dfd0d72f1476da"
),
),
synthetic
=
False
,
)
assert
revision
==
expected_revision
def
test_weird_commit
(
self
):
"""Checks raw_manifest is set when the commit cannot fit the data model"""
# Well-formed manifest
raw_manifest
=
(
b
"tree 641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce
\n
"
b
"author Foo <foo@example.org> 1640191028 +0200
\n
"
b
"committer Foo <foo@example.org> 1640191028 +0200
\n\n
"
b
"some commit message"
)
commit
=
dulwich
.
objects
.
Commit
.
from_raw_string
(
b
"commit"
,
raw_manifest
)
date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1640191028
,
microseconds
=
0
),
offset_bytes
=
b
"+0200"
,
)
assert
converters
.
dulwich_commit_to_revision
(
commit
)
==
Revision
(
message
=
b
"some commit message"
,
directory
=
hash_to_bytes
(
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
),
synthetic
=
False
,
author
=
Person
.
from_fullname
(
b
"Foo <foo@example.org>"
,
),
committer
=
Person
.
from_fullname
(
b
"Foo <foo@example.org>"
,
),
date
=
date
,
committer_date
=
date
,
type
=
RevisionType
.
GIT
,
raw_manifest
=
None
,
)
# Mess with the offset
raw_manifest2
=
raw_manifest
.
replace
(
b
"+0200"
,
b
"+200"
)
commit
=
dulwich
.
objects
.
Commit
.
from_raw_string
(
b
"commit"
,
raw_manifest2
)
date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1640191028
,
microseconds
=
0
),
offset_bytes
=
b
"+200"
,
)
assert
converters
.
dulwich_commit_to_revision
(
commit
)
==
Revision
(
message
=
b
"some commit message"
,
directory
=
hash_to_bytes
(
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
),
synthetic
=
False
,
author
=
Person
.
from_fullname
(
b
"Foo <foo@example.org>"
,
),
committer
=
Person
.
from_fullname
(
b
"Foo <foo@example.org>"
,
),
date
=
date
,
committer_date
=
date
,
type
=
RevisionType
.
GIT
,
raw_manifest
=
None
,
)
# Mess with the rest of the manifest
raw_manifest2
=
raw_manifest
.
replace
(
b
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
,
b
"641FB6E08DDB2E4FD096DCF18E80B894BF7E25CE"
,
)
commit
=
dulwich
.
objects
.
Commit
.
from_raw_string
(
b
"commit"
,
raw_manifest2
)
date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1640191028
,
microseconds
=
0
),
offset_bytes
=
b
"+0200"
,
)
assert
converters
.
dulwich_commit_to_revision
(
commit
)
==
Revision
(
message
=
b
"some commit message"
,
directory
=
hash_to_bytes
(
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
),
synthetic
=
False
,
author
=
Person
.
from_fullname
(
b
"Foo <foo@example.org>"
,
),
committer
=
Person
.
from_fullname
(
b
"Foo <foo@example.org>"
,
),
date
=
date
,
committer_date
=
date
,
type
=
RevisionType
.
GIT
,
raw_manifest
=
b
"commit 161
\x00
"
+
raw_manifest2
,
)
def
test_author_line_to_author
(
self
):
# edge case out of the way
with
pytest
.
raises
(
TypeError
):
converters
.
parse_author
(
None
)
tests
=
{
b
"a <b@c.com>"
:
Person
(
name
=
b
"a"
,
email
=
b
"b@c.com"
,
fullname
=
b
"a <b@c.com>"
,
),
b
"<foo@bar.com>"
:
Person
(
name
=
None
,
email
=
b
"foo@bar.com"
,
fullname
=
b
"<foo@bar.com>"
,
),
b
"malformed <email"
:
Person
(
name
=
b
"malformed"
,
email
=
b
"email"
,
fullname
=
b
"malformed <email"
),
b
"trailing <sp@c.e> "
:
Person
(
name
=
b
"trailing"
,
email
=
b
"sp@c.e"
,
fullname
=
b
"trailing <sp@c.e> "
,
),
b
"no<sp@c.e>"
:
Person
(
name
=
b
"no"
,
email
=
b
"sp@c.e"
,
fullname
=
b
"no<sp@c.e>"
,
),
b
" <>"
:
Person
(
name
=
None
,
email
=
None
,
fullname
=
b
" <>"
,
),
b
"something"
:
Person
(
name
=
b
"something"
,
email
=
None
,
fullname
=
b
"something"
),
}
for
author
in
sorted
(
tests
):
parsed_author
=
tests
[
author
]
assert
parsed_author
==
converters
.
parse_author
(
author
)
def
test_dulwich_tag_to_release_no_author_no_date
(
self
):
sha
=
hash_to_bytes
(
"f6e367357b446bd1315276de5e88ba3d0d99e136"
)
target
=
b
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
message
=
b
"some release message"
tag
=
dulwich
.
objects
.
Tag
()
tag
.
name
=
b
"blah"
tag
.
object
=
(
dulwich
.
objects
.
Commit
,
target
)
tag
.
message
=
message
tag
.
signature
=
None
tag
.
tagger
=
None
tag
.
tag_time
=
None
tag
.
tag_timezone
=
None
assert
tag
.
sha
()
.
digest
()
==
sha
# when
actual_release
=
converters
.
dulwich_tag_to_release
(
tag
)
# then
expected_release
=
Release
(
author
=
None
,
date
=
None
,
id
=
sha
,
message
=
message
,
metadata
=
None
,
name
=
b
"blah"
,
synthetic
=
False
,
target
=
hash_to_bytes
(
target
.
decode
()),
target_type
=
ObjectType
.
REVISION
,
)
assert
actual_release
==
expected_release
def
test_dulwich_tag_to_release_author_and_date
(
self
):
sha
=
hash_to_bytes
(
"fc1e6a4f1e37e93e28e78560e73efd0b12f616ef"
)
tagger
=
b
"hey dude <hello@mail.org>"
target
=
b
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
message
=
b
"some release message"
date
=
int
(
datetime
.
datetime
(
2007
,
12
,
5
,
tzinfo
=
datetime
.
timezone
.
utc
)
.
timestamp
()
)
tag
=
dulwich
.
objects
.
Tag
()
tag
.
name
=
b
"blah"
tag
.
object
=
(
dulwich
.
objects
.
Commit
,
target
)
tag
.
message
=
message
tag
.
signature
=
None
tag
.
tagger
=
tagger
tag
.
tag_time
=
date
tag
.
tag_timezone
=
0
assert
tag
.
sha
()
.
digest
()
==
sha
# when
actual_release
=
converters
.
dulwich_tag_to_release
(
tag
)
# then
expected_release
=
Release
(
author
=
Person
(
email
=
b
"hello@mail.org"
,
fullname
=
b
"hey dude <hello@mail.org>"
,
name
=
b
"hey dude"
,
),
date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1196812800
,
microseconds
=
0
,
),
offset_bytes
=
b
"+0000"
,
),
id
=
sha
,
message
=
message
,
metadata
=
None
,
name
=
b
"blah"
,
synthetic
=
False
,
target
=
hash_to_bytes
(
target
.
decode
()),
target_type
=
ObjectType
.
REVISION
,
)
assert
actual_release
==
expected_release
def
test_dulwich_tag_to_release_author_no_date
(
self
):
# to reproduce bug T815 (fixed)
sha
=
hash_to_bytes
(
"41076e970975122dc6b2a878aa9797960bc4781d"
)
tagger
=
b
"hey dude <hello@mail.org>"
target
=
b
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
message
=
b
"some release message"
tag
=
dulwich
.
objects
.
Tag
()
tag
.
name
=
b
"blah"
tag
.
object
=
(
dulwich
.
objects
.
Commit
,
target
)
tag
.
message
=
message
tag
.
signature
=
None
tag
.
tagger
=
tagger
tag
.
tag_time
=
None
tag
.
tag_timezone
=
None
assert
tag
.
sha
()
.
digest
()
==
sha
# when
actual_release
=
converters
.
dulwich_tag_to_release
(
tag
)
# then
expected_release
=
Release
(
author
=
Person
(
email
=
b
"hello@mail.org"
,
fullname
=
b
"hey dude <hello@mail.org>"
,
name
=
b
"hey dude"
,
),
date
=
None
,
id
=
sha
,
message
=
message
,
metadata
=
None
,
name
=
b
"blah"
,
synthetic
=
False
,
target
=
hash_to_bytes
(
target
.
decode
()),
target_type
=
ObjectType
.
REVISION
,
)
assert
actual_release
==
expected_release
def
test_dulwich_tag_to_release_author_zero_date
(
self
):
# to reproduce bug T815 (fixed)
sha
=
hash_to_bytes
(
"6cc1deff5cdcd853428bb63b937f43dd2566c36f"
)
tagger
=
b
"hey dude <hello@mail.org>"
target
=
b
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
message
=
b
"some release message"
date
=
int
(
datetime
.
datetime
(
1970
,
1
,
1
,
tzinfo
=
datetime
.
timezone
.
utc
)
.
timestamp
()
)
tag
=
dulwich
.
objects
.
Tag
()
tag
.
name
=
b
"blah"
tag
.
object
=
(
dulwich
.
objects
.
Commit
,
target
)
tag
.
message
=
message
tag
.
signature
=
None
tag
.
tagger
=
tagger
tag
.
tag_time
=
date
tag
.
tag_timezone
=
0
assert
tag
.
sha
()
.
digest
()
==
sha
# when
actual_release
=
converters
.
dulwich_tag_to_release
(
tag
)
# then
expected_release
=
Release
(
author
=
Person
(
email
=
b
"hello@mail.org"
,
fullname
=
b
"hey dude <hello@mail.org>"
,
name
=
b
"hey dude"
,
),
date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
0
,
microseconds
=
0
,
),
offset_bytes
=
b
"+0000"
,
),
id
=
sha
,
message
=
message
,
metadata
=
None
,
name
=
b
"blah"
,
synthetic
=
False
,
target
=
hash_to_bytes
(
target
.
decode
()),
target_type
=
ObjectType
.
REVISION
,
)
assert
actual_release
==
expected_release
def
test_dulwich_tag_to_release_signature
(
self
):
target
=
b
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
message
=
b
"some release message"
sha
=
hash_to_bytes
(
"46fff489610ed733d2cc904e363070dadee05c71"
)
tag
=
dulwich
.
objects
.
Tag
()
tag
.
name
=
b
"blah"
tag
.
object
=
(
dulwich
.
objects
.
Commit
,
target
)
tag
.
message
=
message
tag
.
signature
=
GPGSIG
tag
.
tagger
=
None
tag
.
tag_time
=
None
tag
.
tag_timezone
=
None
assert
tag
.
sha
()
.
digest
()
==
sha
# when
actual_release
=
converters
.
dulwich_tag_to_release
(
tag
)
# then
expected_release
=
Release
(
author
=
None
,
date
=
None
,
id
=
sha
,
message
=
message
+
GPGSIG
,
metadata
=
None
,
name
=
b
"blah"
,
synthetic
=
False
,
target
=
hash_to_bytes
(
target
.
decode
()),
target_type
=
ObjectType
.
REVISION
,
)
assert
actual_release
==
expected_release
@pytest.mark.parametrize
(
"attribute"
,
[
"name"
,
"message"
,
"signature"
])
def
test_corrupt_tag
(
self
,
attribute
):
sha
=
hash_to_bytes
(
"46fff489610ed733d2cc904e363070dadee05c71"
)
target
=
b
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
message
=
b
"some release message"
tag
=
dulwich
.
objects
.
Tag
()
tag
.
name
=
b
"blah"
tag
.
object
=
(
dulwich
.
objects
.
Commit
,
target
)
tag
.
message
=
message
tag
.
signature
=
GPGSIG
tag
.
tagger
=
None
tag
.
tag_time
=
None
tag
.
tag_timezone
=
None
assert
tag
.
sha
()
.
digest
()
==
sha
converters
.
dulwich_tag_to_release
(
tag
)
original_sha
=
tag
.
sha
()
setattr
(
tag
,
attribute
,
b
"abcde"
)
tag
.
sha
()
# reset tag._needs_serialization
tag
.
_sha
=
original_sha
# force the wrong hash
with
pytest
.
raises
(
converters
.
HashMismatch
):
converters
.
dulwich_tag_to_release
(
tag
)
if
attribute
==
"signature"
:
setattr
(
tag
,
attribute
,
None
)
tag
.
sha
()
# reset tag._needs_serialization
tag
.
_sha
=
original_sha
# force the wrong hash
with
pytest
.
raises
(
converters
.
HashMismatch
):
converters
.
dulwich_tag_to_release
(
tag
)
def
test_weird_tag
(
self
):
"""Checks raw_manifest is set when the tag cannot fit the data model"""
# Well-formed manifest
raw_manifest
=
(
b
"object 641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce
\n
"
b
"type commit
\n
"
b
"tag blah
\n
"
b
"tagger Foo <foo@example.org> 1640191027 +0200
\n\n
"
b
"some release message"
)
tag
=
dulwich
.
objects
.
Tag
.
from_raw_string
(
b
"tag"
,
raw_manifest
)
assert
converters
.
dulwich_tag_to_release
(
tag
)
==
Release
(
name
=
b
"blah"
,
message
=
b
"some release message"
,
target
=
hash_to_bytes
(
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
),
target_type
=
ObjectType
.
REVISION
,
synthetic
=
False
,
author
=
Person
.
from_fullname
(
b
"Foo <foo@example.org>"
,
),
date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1640191027
,
microseconds
=
0
),
offset_bytes
=
b
"+0200"
,
),
raw_manifest
=
None
,
)
# Mess with the offset (negative UTC)
raw_manifest2
=
raw_manifest
.
replace
(
b
"+0200"
,
b
"-0000"
)
tag
=
dulwich
.
objects
.
Tag
.
from_raw_string
(
b
"tag"
,
raw_manifest2
)
assert
converters
.
dulwich_tag_to_release
(
tag
)
==
Release
(
name
=
b
"blah"
,
message
=
b
"some release message"
,
target
=
hash_to_bytes
(
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
),
target_type
=
ObjectType
.
REVISION
,
synthetic
=
False
,
author
=
Person
.
from_fullname
(
b
"Foo <foo@example.org>"
,
),
date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1640191027
,
microseconds
=
0
),
offset_bytes
=
b
"-0000"
,
),
)
# Mess with the offset (other)
raw_manifest2
=
raw_manifest
.
replace
(
b
"+0200"
,
b
"+200"
)
tag
=
dulwich
.
objects
.
Tag
.
from_raw_string
(
b
"tag"
,
raw_manifest2
)
assert
converters
.
dulwich_tag_to_release
(
tag
)
==
Release
(
name
=
b
"blah"
,
message
=
b
"some release message"
,
target
=
hash_to_bytes
(
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
),
target_type
=
ObjectType
.
REVISION
,
synthetic
=
False
,
author
=
Person
.
from_fullname
(
b
"Foo <foo@example.org>"
,
),
date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1640191027
,
microseconds
=
0
),
offset_bytes
=
b
"+200"
,
),
)
# Mess with the rest of the manifest
raw_manifest2
=
raw_manifest
.
replace
(
b
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
,
b
"641FB6E08DDB2E4FD096DCF18E80B894BF7E25CE"
,
)
tag
=
dulwich
.
objects
.
Tag
.
from_raw_string
(
b
"tag"
,
raw_manifest2
)
assert
converters
.
dulwich_tag_to_release
(
tag
)
==
Release
(
name
=
b
"blah"
,
message
=
b
"some release message"
,
target
=
hash_to_bytes
(
"641fb6e08ddb2e4fd096dcf18e80b894bf7e25ce"
),
target_type
=
ObjectType
.
REVISION
,
synthetic
=
False
,
author
=
Person
.
from_fullname
(
b
"Foo <foo@example.org>"
,
),
date
=
TimestampWithTimezone
(
timestamp
=
Timestamp
(
seconds
=
1640191027
,
microseconds
=
0
),
offset_bytes
=
b
"+0200"
,
),
raw_manifest
=
b
"tag 136
\x00
"
+
raw_manifest2
,
)
File Metadata
Details
Attached
Mime Type
text/x-python
Expires
Fri, Jul 4, 2:52 PM (4 d, 15 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3331912
Attached To
rDLDG Git loader
Event Timeline
Log In to Comment